R 始终使用列表中n个其他数据帧中的一行创建所有可能的数据帧

R 始终使用列表中n个其他数据帧中的一行创建所有可能的数据帧,r,R,我有一个数据帧,它按id被拆分成一个列表,如下所示。现在我想创建一个所有可能组合的数据帧列表,始终只使用列表中每个数据帧的一行。我已经在lappy调用中尝试了expand.grid和combn,使用names(data)索引数据帧,但我不知道怎么做 使用iris数据集,这里有一个简短的示例: library(dplyr) # data iris %>% select(Sepal.Length,Sepal.Width,Species) %>% mutate_if(is.num

我有一个数据帧,它按id被拆分成一个列表,如下所示。现在我想创建一个所有可能组合的数据帧列表,始终只使用列表中每个数据帧的一行。我已经在
lappy
调用中尝试了
expand.grid
combn
,使用
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]]...

谢谢你的建议

这里有一个
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\u 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

也许有更好的方法可以做到这一点,但是使用base 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

我会尝试使用purrr的reduce和tidyr的crossing函数:
data\u split%select(Sepal.Length,Sepal.Width,Species)%%>%mutate\u如果(is.numeric,round,0)%%>%distinct()%%>%split(.$Species)reduce(data\u split,crossing)
这将为您提供一个包含所有组合的数据框架。但是它们的格式很宽,因此您必须进行更多的数据包装。这有帮助吗?这是一个良好的开端,但它不会产生预期的输出,如下面的答案。
lst <- iris %>%
         select(Sepal.Length,Sepal.Width,Species) %>%
         mutate_if(is.numeric,round,0) %>%
         distinct() %>%
         split(., .$Species)