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

expand.grid with separate variable for each column

我想在 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")))

我猜你可以创建自己的辅助函数,类似的东西

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.tables CJ 等价物,对于大的 n

,它应该比 expand.grid 更有效
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

另一种选择是使用 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')))

另一种选择,仅使用 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)

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

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