expand.grid,每列有单独的变量

时间:2015-01-10 21:39:29

标签: r combinations

我想在R中实现以下data.frame

    i1   i2   i3
1   A1   A2   A3
2   No   A2   A3
3   A1   No   A3
4   No   No   A3
5   A1   A2   No
6   No   A2   No
7   A1   No   No
8   No   No   No

在每列中,变量可以是连接字符串" A" 和列号或" No" data.frame应包含所有可能的组合。

我的想法是使用expand.grid,但我不知道如何动态创建list。或者有更好的方法吗?

expand.grid(list(c("A1", "No"), c("A2", "No"), c("A3", "No")))

3 个答案:

答案 0 :(得分:6)

我猜你可以创建自己的辅助函数,就像那样

MyList <- function(n) expand.grid(lapply(paste0("A", seq_len(n)), c, "No"))

然后简单地传递元素的数量(例如,3)

MyList(3)
#   Var1 Var2 Var3
# 1   A1   A2   A3
# 2   No   A2   A3
# 3   A1   No   A3
# 4   No   No   A3
# 5   A1   A2   No
# 6   No   A2   No
# 7   A1   No   No
# 8   No   No   No

或者,您也可以尝试使用data.table CJ等效文件,这对于大expand.grid

而言应该比n更有效率
library(data.table)
DTCJ <- function(n) do.call(CJ, lapply(paste0("A", seq_len(n)), c, "No"))
DTCJ(3) # will return a sorted cross join
#    V1 V2 V3
# 1: A1 A2 A3
# 2: A1 A2 No
# 3: A1 No A3
# 4: A1 No No
# 5: No A2 A3
# 6: No A2 No
# 7: No No A3
# 8: No No No

答案 1 :(得分:2)

另一种选择是将Mapexpand.grid

一起使用
 n <- 3
 expand.grid(Map(c, paste0('A', seq_len(n)), 'NO'))

或者

 expand.grid(as.data.frame(rbind(paste0('A', seq_len(n)),'NO')))

答案 2 :(得分:0)

另一个选项,只使用R中最基本的函数,是使用索引:

df <- data.frame(V1 = c('A','A','A', 'A',rep('No',4)), V2 = c('A','A','No','No','A','A','No','No'), V3 = c('A','No','A','No','A','No','A','No'), stringsAsFactors = FALSE)

获取我们需要更改的元素的行和col索引:

rindex <- which(df != 'No') %% nrow(df)
cindex <- ceiling(which(df != 'No')/nrow(df))

解决方案基本上是单行的:

df[matrix(c(rindex,cindex),ncol=2)] <- paste0(df[matrix(c(rindex,cindex),ncol=2)],cindex)

> df

  V1 V2 V3
1 A1 A2 A3
2 A1 A2 No
3 A1 No A3
4 A1 No No
5 No A2 A3
6 No A2 No
7 No No A3
8 No No No