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

时间:2019-06-17 10:06:01

标签: r

我有一个数据框,该数据框按其ID分为一个列表,如下所示。现在,我想创建一个所有可能组合的数据框列表,始终只使用列表中每个数据框的一行。我已经在expand.grid的{​​{1}}调用中使用combnlapplynames(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 个答案:

答案 0 :(得分:1)

这是一种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

答案 1 :(得分:1)

可能应该有更好的方法,但是使用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

lst

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