Создайте все возможные фреймы данных, используя всегда одну строку из n других фреймов данных в списке - PullRequest
1 голос
/ 17 июня 2019

У меня есть фрейм данных, который разделен на список по его идентификатору, как показано ниже. Теперь я хотел бы создать список фреймов данных всех возможных комбинаций, всегда используя только одну строку каждого фрейма данных в списке. Я уже экспериментировал с expand.grid и combn в вызове lapply, используя names(data) для индексации кадров данных, но не могу понять, как это сделать.

Использование набора данных iris вот краткий пример:

library(dplyr)

# data
iris %>%
  select(Sepal.Length,Sepal.Width,Species) %>%
  mutate_if(is.numeric,round,0) %>%
  distinct() %>%
  split(.,.$Species)

# This is what you get
$`setosa`
  Sepal.Length Sepal.Width Species
1            5           4  setosa
2            5           3  setosa
3            4           3  setosa
4            6           4  setosa
5            4           2  setosa

$versicolor
   Sepal.Length Sepal.Width    Species
6             7           3 versicolor
7             6           3 versicolor
8             6           2 versicolor
9             5           2 versicolor
10            5           3 versicolor

$virginica
   Sepal.Length Sepal.Width   Species
11            6           3 virginica
12            7           3 virginica
13            8           3 virginica
14            5           2 virginica
15            7           2 virginica
16            7           4 virginica
17            6           2 virginica
18            8           4 virginica

И теперь я хочу получить все возможные кадры данных, всегда используя одну строку каждого кадра данных в приведенном выше списке, например:

$[[1]]
  Sepal.Length Sepal.Width Species
1            5           4 setosa
6            7           3 versicolor
11           6           3 virginica

$[[2]]...

Спасибо за ваши предложения!

Ответы [ 2 ]

1 голос
/ 17 июня 2019

Вероятно, должен быть лучший способ сделать это, но одним из способов использования базы R, где она должна работать для любого количества групп, является

#Find all possible combinations of row indices for each list
row_combns <- do.call(expand.grid, lapply(lst, function(x) seq(nrow(x))))

#Make one big dataframe combining all possible combination subsetting 
#it from corresponding list element
df1 <- do.call(rbind, lapply(seq_along(lst), 
               function(x) lst[[x]][row_combns[[x]], ]))

#Create a grouping index
df1$index <- seq_len(nrow(row_combns))
#Use the index to split
split(df1, df1$index)

#.....
#$`199`
#      Sepal.Length Sepal.Width    Species index
#4.39             6           4     setosa   199
#10.38            5           3 versicolor   199
#18.23            8           4  virginica   199

#$`200`
#      Sepal.Length Sepal.Width    Species index
#5.39             4           2     setosa   200
#10.39            5           3 versicolor   200
#18.24            8           4  virginica   200

, где lst равно

lst <- iris %>%
         select(Sepal.Length,Sepal.Width,Species) %>%
         mutate_if(is.numeric,round,0) %>%
         distinct() %>%
         split(., .$Species)
1 голос
/ 17 июня 2019

Вот подход tidyverse:

library(tidyverse)

# update data
iris %>%
  select(Sepal.Length,Sepal.Width,Species) %>%
  mutate_if(is.numeric,round,0) %>%
  distinct() %>%
  mutate(Species = as.character(Species)) -> iris_upd

iris_upd %>%
  split(.,.$Species) %>%               # split by species column
  reduce(crossing) %>%                 # create all row combinations
  group_nest(id = row_number()) %>%    # group by row id
  mutate(d = map(data, ~{d = data.frame(t(matrix(., nrow=3, ncol=ncol(iris_upd))))  # reshape data
                         names(d) = names(iris_upd)                                 # set column mnames
                         d})) -> iris_comb

Теперь в наборе данных iris_comb есть столбец d, содержащий все необходимые комбинации:

iris_comb$d

# .....
#
# [[199]]
# Sepal.Length Sepal.Width    Species
# 1            4           2     setosa
# 2            5           3 versicolor
# 3            6           2  virginica
# 
# [[200]]
# Sepal.Length Sepal.Width    Species
# 1            4           2     setosa
# 2            5           3 versicolor
# 3            8           4  virginica
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...