expand.grid 后跟do.call 怎么样?
cart_prod <- expand.grid(c("A", "T", "C", "G"),
"G",
c("A", "T", "C", "G"),
"G")
do.call(paste0, cart_prod)
[1] "AGAG" "TGAG" "CGAG" "GGAG" "AGTG" "TGTG" "CGTG" "GGTG"
[9] "AGCG" "TGCG" "CGCG" "GGCG" "AGGG" "TGGG" "CGGG" "GGGG"
说明
由于 OP 要求索引 2 和 4 保持为“G”,我们只需让第一个 1st 和 3rd 参数在可能的选择上有所不同:@ 987654326@。现在,使用前 4 个参数调用 expand.grid:
c("A", "T", "C", "G")
"G"
c("A", "T", "C", "G")
"G"
将产生一个与我们想要的结果同构的data.frame,因为expand.grid 返回Cartesian product。
expand.grid(c("A", "T", "C", "G"),
"G",
c("A", "T", "C", "G"),
"G")
Var1 Var2 Var3 Var4
1 A G A G
2 T G A G
3 C G A G
4 G G A G
5 A G T G
6 T G T G
7 C G T G
8 G G T G
9 A G C G
10 T G C G
11 C G C G
12 G G C G
13 A G G G
14 T G G G
15 C G G G
16 G G G G
现在,剩下的就是将列粉碎在一起。我们利用do.call 和paste0 来实现这一点。
为什么do.call(paste0, some_data.frame) 有效?
我在do.call 上找到了这个很好的解释:The {do.call} function。这是第一行:
“R 有一个有趣的函数,叫做 do.call。这个函数允许你调用任何 R 函数,但是你可以使用一个列表来保存函数的参数,而不是一个一个地写出参数。”
由于data.frame 本质上是一个list,我们可以按照通常的方式使用do.call。
由于cart_prod 的每一列只是一个向量,paste0 按元素组合每一列。例如,第一列和第二列是:
cart_prod$Var1
[1] A T C G A T C G A T C G A T C G
Levels: A T C G
cart_prod$Var2
[1] G G G G G G G G G G G G G G G G
Levels: G
将paste0 应用于这两个,给出:
paste0(cart_prod$Var1, cart_prod$Var2)
[1] "AG" "TG" "CG" "GG" "AG" "TG" "CG" "GG"
[9] "AG" "TG" "CG" "GG" "AG" "TG" "CG" "GG"
如您所见,我们开始看到我们想要的结果。如果我们将此结果与第三列结合,我们将得到:
paste0(paste0(cart_prod$Var1, cart_prod$Var2), cart_prod$Var3)
[1] "AGA" "TGA" "CGA" "GGA" "AGT" "TGT" "CGT" "GGT"
[9] "AGC" "TGC" "CGC" "GGC" "AGG" "TGG" "CGG" "GGG"
现在,我们将这个结果与最后一列结合起来:
paste0(paste0(paste0(cart_prod$Var1, cart_prod$Var2), cart_prod$Var3), cart_prod$Var4)
[1] "AGAG" "TGAG" "CGAG" "GGAG" "AGTG" "TGTG" "CGTG" "GGTG"
[9] "AGCG" "TGCG" "CGCG" "GGCG" "AGGG" "TGGG" "CGGG" "GGGG"
瞧!我们得到了我们想要的结果。