9

我有一个氨基酸位点的数据框,并且想为这些位点的每个成对组合创建一个新的数据框。

原始数据将如下所示:

df<-cbind(letters[1:5], letters[6:10], letters[11:15])
df
 [,1] [,2] [,3] 
[1,] "a"  "f"  "k" 
[2,] "b"  "g"  "l" 
[3,] "c"  "h"  "m" 
[4,] "d"  "i"  "n" 
[5,] "e"  "j"  "o" 

我想要的是:

newdf<-cbind(paste(df[,1],df[,2],sep=""),paste(df[,1],df[,3],sep=""),(paste(df[,2],df[,3],sep="")))
newdf
     [,1] [,2] [,3]
[1,] "af" "ak" "fk"
[2,] "bg" "bl" "gl"
[3,] "ch" "cm" "hm"
[4,] "di" "dn" "in"
[5,] "ej" "eo" "jo"

实际数据可能有数百行和/或列,因此显然我需要一种较少手动的方式来执行此操作。非常感谢任何帮助,我只是一个谦虚的生物学家,我在这方面的技能相当有限。

4

4 回答 4

12

combn()和的组合apply()将为您提供所有无序的成对组合:

df <- cbind(letters[1:5], letters[6:10], letters[11:15])

apply(X = combn(seq_len(ncol(df)), 2), 
      MAR = 2, 
      FUN = function(jj) {
          apply(df[, jj], 1, paste, collapse="")
      }      
)
#      [,1] [,2] [,3]
# [1,] "af" "ak" "fk"
# [2,] "bg" "bl" "gl"
# [3,] "ch" "cm" "hm"
# [4,] "di" "dn" "in"
# [5,] "ej" "eo" "jo"

(如果上面发生的事情不是很清楚,您可能想快速查看由 . 返回的对象combn(seq_len(ncol(df)), 2)。它的列枚举了 1 和 之间的所有无序成对组合整数n,其中n是数据框中的列数.)

于 2012-07-31T00:05:41.683 回答
9

您可以使用FUN参数将combn每个组合中的列粘贴在一起:

combn(ncol(df),2,FUN=function(i) apply(df[,i],1,paste0,collapse=""))
于 2012-07-31T00:36:10.300 回答
2

乔希和约书亚的答案更好,但我想我会给出我的方法:

这需要使用以下功能下载qdapvarsion 1.1.0 :paste2

library(qdap)

ind <- unique(t(apply(expand.grid(1:3, 1:3), 1, sort)))
ind <- ind[ind[, 1] != ind[, 2], ]
sapply(1:nrow(ind), function(i) paste2(df[, unlist(ind[i, ])], sep=""))

虽然从他们的答案中窃取这将更具可读性:

ind <- t(combn(seq_len(ncol(df)), 2))
sapply(1:nrow(ind), function(i) paste2(df[, unlist(ind[i, ])], sep=""))
于 2012-07-31T01:24:08.830 回答
-1

请记住,您将在新 data.frame 中获得很多列,假设您说原始 data.frame 中有数百列:如果原始数据包含n列,那么新数据将包含n(n- 1)/2列 - 这是二次缩放的。

于 2012-07-31T06:19:29.540 回答