Я изо всех сил пытаюсь создать функцию в R, которая будет принимать набор данных и столбцы и выводить каждую перестановку наборов данных, отфильтрованных по всем этим трем столбцам.

Мой набор данных выглядит так

structure(list(name = c("Peter Doe", "John Gary", "Elsa Johnson", 
"Mary Poppins", "Jesse Bogart"), sex = c("Male", "Male", "Female", 
"Female", "Male"), class = c("Honors", "Core", "Core", "Honors", 
"Honors"), grade = c("A", "A", "A", "B", "C")), class = c("tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -5L))

Я попытался визуализировать свою цель здесь: Я попытался визуализировать здесь свою цель

Я надеялся создать новые переменные в зависимости от того, по какому пути этой карты он следовал (например, male_honors_a <- набор данных, отфильтрованный по этим значениям столбца), и я думаю, что мог бы сделать это с помощью функции вставки, но я не уверен и здесь. Что еще более важно, я борюсь с тем, как объединить циклы внутри функции, которые могут фильтровать на основе уникальных значений столбца.

Я дошел до того, что написал функцию, которая создает каждую подгруппу по отдельности, но не смог понять, как их объединить.

subgroups <- function(df, filters, group = "none", name = ""){
  listofdfs <- list()
  for (i in filters) {
    subgroups <- unique(df[[i]])
    for (j in subgroups){
      x <- df[df[i] == j,]
      listofdfs[[paste(name,j, sep = "")]] <- x
    }
  }
  if (group != "none"){
    return(listofdfs[[group]])
  }
  else {
  return(listofdfs)}
}

subgroups(df, c("sex", "class", "grade"))

Я надеюсь, что запустив subgroups(df, c("sex", "class")), я выведу список фреймов данных:

list(male_honors, male_core, female_honors, female_core)

В котором элемент male_honors

# A tibble: 2 × 4
  name         sex   class  grade
1 Peter Doe    Male  Honors A    
2 Jesse Bogart Male  Honors C   

Был бы очень признателен за любую помощь!

1
Lilly Shaw 19 Янв 2022 в 07:32
Добро пожаловать в Stack Overflow! Я могу сказать, что вы приложили много усилий и усилий к этой функции. Не могли бы вы добавить еще одну функцию: включить элементы из Как сделать отличный R воспроизводимый пример?. Особенно аспекты использования dput() для ввода, а затем явный пример ожидаемого набора данных?
 – 
wibeasley
19 Янв 2022 в 07:38
1
Привет @wibeasley! Спасибо за прием! Я только что попытался добавить ваши предложения - дайте мне знать, если это поможет!
 – 
Lilly Shaw
19 Янв 2022 в 07:57

3 ответа

Функция cross() может помочь

0
Julian Tagell 19 Янв 2022 в 08:07

tidyr::nest() делает это напрямую. Обратите внимание, что для каждой комбинации группирующих/вложенных переменных табличка аккуратно помещается в ячейку data. Я немного изменил вашу функцию, (а) удалив аспекты, не связанные с группировкой (например, фильтр), и (б) сделав groups по умолчанию пустым вектором символов, поэтому, если ничего не передано, ничего не сгруппировано.

Кроме того, имена (например,, мужские почести) легко получить с помощью переменных значений. Обычно это намного полезнее, чем извлечение значений из имен переменных.

Подойдет ли это для ваших целей?

subgroups <- function(df, groups = character(0)) {
  df |> 
    tidyr::nest(data = -groups)
}
> subgroups(ds, c("class", "sex"))
# # A tibble: 4 × 3
#   sex    class  data            
#   <chr>  <chr>  <list>          
# 1 Male   Honors <tibble [2 × 2]>
# 2 Male   Core   <tibble [1 × 2]>
# 3 Female Core   <tibble [1 × 2]>
# 4 Female Honors <tibble [1 × 2]>

> subgroups(ds, c("sex"))
# # A tibble: 2 × 2
#   sex    data            
#   <chr>  <list>          
# 1 Male   <tibble [3 × 3]>
# 2 Female <tibble [2 × 3]>

> subgroups(ds)
# # A tibble: 1 × 1
#   data            
#   <list>          
# 1 <tibble [5 × 4]>

Дополнительные ресурсы: виньетка вложенных данных от tidyr.

0
wibeasley 19 Янв 2022 в 08:23

Вы можете создать ключ столбца, который будет использоваться для фильтрации. Уникальный ключ можно использовать для циклического просмотра каждого подмножества вашего фрейма данных. Вот решение с вашими данными как df и желаемым результатом списка как l.

library(dplyr)
#make a key (constructed of 2 or more column values)
df<- df  |>  mutate(key = paste0(sex, "_", class))
#get the unqiue keys
keys<-unique(df$key)
#make an empty list
l<-list()
#loop through unique keys to filter your df, removing the key column 
for(x in 1:length(keys)){
  l[[x]]<-df[df$key ==keys[x],]  |> select(!key)
}
#name list elements
names(l)<-tolower(keys)
# your desired result
l
0
SEAnalyst 19 Янв 2022 в 08:56