R

时间:2016-03-17 23:01:28

标签: r comparison sequence

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

        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之间相同的站点。 / p>

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

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

提前致谢!

2 个答案:

答案 0 :(得分:1)

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

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)

答案 1 :(得分:0)

这是一种快速而又脏的方法来创建您提到的标志。假设数据帧被称为氨基酸:

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()函数,它通常根据向量或像表(氨基$ seq1)之类的列给出计数。使用apply,我们将8个序列中的一行放入其中,它返回计数,然后我们使用as.data.frame和括号[]来删除一些我们不需要的额外table()输出。 “7%in%”部分表示如果有7个相同的字母则必须有1个不同的字母。其他任何东西(即所有8个相同或超过1个差异)都将获得NA。