【问题标题】:Combine all possible rows of data frame in R在R中组合所有可能的数据框行
【发布时间】:2018-11-29 19:32:30
【问题描述】:

我有以下数据框:

x <- data.frame("Col1" = c('A', 'B', 'C', 'D'), "Col2" = c('W', 'X', 'Y', 'Z'))

我想要一个新的数据框,其中包含所有可能的行组合组合,这将提供一个包含两列的数据框,其中包含以下内容:

A W
A X
A Y
A Z
B W
B X
B Y
B Z
C W
...

数据框总是有两列,但行数可能会有所不同。

我查看了 permute() 或 sample() 但我没有设法得到我想要的东西。 谢谢!

【问题讨论】:

标签: r dataframe permute


【解决方案1】:

tidyr::complete() 就是为此而设计的。我很惊讶我没有在 SO 上看到一个普通的例子。

library(magrittr)
x %>% 
  tidyr::complete(Col1, Col2)

结果:

# A tibble: 16 x 2
   Col1  Col2 
   <fct> <fct>
 1 A     W    
 2 A     X    
 3 A     Y    
 4 A     Z    
 5 B     W    
 6 B     X    
 7 B     Y    
 8 B     Z    
 9 C     W    
10 C     X    
11 C     Y    
12 C     Z    
13 D     W    
14 D     X    
15 D     Y    
16 D     Z    

如果你的真实场景像 OP 一样简单,@bouncyball 的expand.grid(x) 建议是最干净的。如果您的实际场景更加复杂,那么tidyr::complete() 可能会让您更轻松地成长。我通常有两个以上的 ID 变量来扩展/完成。这些通常是分析的因变量/结果变量,fill 参数允许您为观察数据集中未出现的组合指定它们的默认值。这是SO example

经过编辑以反映 @bouncyball 和 @ADuv 的建议。

【讨论】:

  • 我明白你的意思,我都喜欢。您也可以卸下管道并使其成为一条线。我更喜欢complete(),因为(a)顺序与 OP 的目标输出相匹配(左列的变化比右列慢)和(b)如果数据集包含您不想要的其他变量,它可能更自然交叉(如使用fill 参数的this example)。
  • 如果这是唯一的目标,并且您不在其他地方使用tidyverse,我推荐expand.grid(),因为小标题与data.frames 是不同的类,并且会引入奇怪的class 问题。但是,是的,取决于 OP 的目标。至少他现在有两种不同的解决方案可以尝试。
  • 你们俩都是对的。我将编辑我的回复并退回“最干净”的声明。我在@bouncyball 的 OP 评论之前写过,不记得 expand.grid() 接受了整个 data.frames。
【解决方案2】:

关于tidyr::completebase::expand.grid,性能也可能是一个因素。

根据下面的基准complete 慢得多,尽管差异随着输入大小而减小。

df <- data.frame(a= 1:10,b= 1:10)
# microbenchmark(complete(df,a,b), expand.grid(df))
# Unit: microseconds
#               expr       min       lq       mean    median        uq       max neval
# complete(df, a, b) 15345.348 16065.27 17947.2132 16609.512 17351.317 46415.772   100
#    expand.grid(df)   129.194   144.74   174.8799   194.395   201.337   256.577   100

df <- data.frame(a= 1:100,b= 1:100)
# microbenchmark(complete(df,a,b), expand.grid(df))
# Unit: microseconds
#               expr       min         lq       mean     median        uq      max neval
# complete(df, a, b) 15992.523 16380.1030 17743.4860 16611.4730 16998.149 26622.31   100
#    expand.grid(df)   323.588   340.4925   376.6481   383.6575   397.844   665.89   100

df <- data.frame(a= 1:1000,b= 1:1000)
microbenchmark(complete(df,a,b), expand.grid(df))
# Unit: milliseconds
#               expr      min       lq     mean   median       uq       max neval
# complete(df, a, b) 86.58981 88.49813 98.73944 93.62617 98.83436 157.40141   100
#    expand.grid(df) 18.99899 19.40211 21.83331 21.20161 23.71123  33.19729   100

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-15
    • 1970-01-01
    相关资源
    最近更新 更多