R中数据框中列之间的差异数

Number of differences between columns in a data frame in R

我有一个数据框,其中序列作为列,氨基酸位点作为行。我想在每个站点比较这些序列之间的差异。

        seq1 seq2 seq3 seq4 seq5 seq6 seq7 seq8   
1      K    E    K    K    A    A    A    A
2      V    D    A    A    T    A    A    A
3      W    W    W    W    W    W    W    W
4      R    R    R    R    R    R    S    R
5      F    S    F    F    F    Y    F    F
6      P    P    P    P    P    P    P    P
7      N    N    N    C    N    N    N    N
8      V    I    D    D    Q    Q    Q    Q
9      Q    Q    Q    Q    Q    Q    Q    Q
10     E    E    G    G    L    I    S    F
11     L    L    Q    L    L    L    L    L
12     N    N    Y    Y    V    V    S    S
13     N    N    N    N    Q    Q    P    P
14     L    L    L    L    L    L    L    L
15     T    T    T    T    T    T    T    I

理想情况下,我希望能够在我的数据框中增加一列,向我显示所有序列中相同的位点以及仅在 seq1-4 或 seq 5-8 之间相同的位点.

我不确定最好的方法是什么,非常感谢您的帮助。

此外,有没有办法添加另一列来显示在每个位点观察到的氨基酸类型?

提前致谢!

这是创建您提到的标志的一种快速而肮脏的方法。假设数据框称为 amino:

amino$first_flag<-with(amino,ifelse(seq1==seq2 & seq2==seq3 & seq3 == seq4,"same","diff"))
amino$second_flag<-with(amino,ifelse(seq5==seq6 & seq6==seq7 & seq7 == seq8,"same","diff"))
amino$total_flag<-with(amino,ifelse(first_flag=="same" & second_flag=="same" & seq1==seq5,"same","diff"))

希望有用。

编辑:对于你的最后一个问题,我不确定你的意思,但如果你只想要出现在每一行中的字母,那么这样的事情可能会起作用:

for(i in 1:nrow(amino)) amino$types[i]<-paste(unique(amino[i,1:4,drop=TRUE]),collapse=",")

它将为您提供一列,其中包含每行中出现的以逗号分隔的字母列表。

edit2:如果序列明显多于 8 个,那么 Ganesh 解决方案的修改形式可能效果更好(实际上不需要他的输出代码):

amino$first_flag <- apply(amino[,1:4],1,function(x){
    ifelse(length(unique(x)) == 1,"same","diff")
})
amino$second_flag <- apply(amino[,5:8],1,function(x){
    ifelse(length(unique(x)) == 1,"same","diff")
})
amino$total_flag <- apply(amino[,1:8],1,function(x){
    ifelse(length(unique(x)) == 1,"same","diff")
})
amino$types <- apply(amino[,1:8],1,function(x) paste(unique(x),collapse=","))

对于你的新问题-

amino$one_diff <- apply(amino[,1:8],1,function(x){
    ifelse(7 %in% as.data.frame(table(x))[,2,drop=TRUE],"1 diff",NA)
})

这使用 table() 函数,该函数通常会根据向量或列(如 table(amino$seq1))为您提供计数。使用 apply,我们改为将 8 个序列的一行插入其中,它 returns 计数,然后我们使用 as.data.frame 和方括号 [] 去除一些额外的 table()我们不需要的输出。 “7 %in%”部分表示如果有 7 个相同的字母,则必须有 1 个不同的字母。其他任何东西(即所有 8 个相同或超过 1 个差异)都将得到 NA。

我首先得到一个所有列都相同的数组:

allsame <- apply(df,1,function(x){
 val <- ifelse(length(unique(x)) == 1,1,0)
})

接下来我得到一个数组,其中任一列集都相同

startfour <- apply(df[,1:4],1,function(x){
  val <- ifelse(length(unique(x)) == 1,1,0)
})
lastfour <- apply(df[,5:8],1,function(x){
  val <- ifelse(length(unique(x)) == 1,1,0)
})
gen <- startfour + lastfour
eithersame <- ifelse(gen == 0,0,1)

最后,您可以根据需要创建一个列向量,并使用上述 2 个数组将其连接到数据框

output <- as.character(length(allsame))
for(i in 1:length(allsame)){
if(allsame[i] == 1){
   output[i] <- "all same"
}
else if(eithersame[i] == 1){
   output[i] <- "either same"
}
else{
   output[i] <- "none same"
}
}
df <- cbind(df,output)