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)
我有一个数据框,其中序列作为列,氨基酸位点作为行。我想在每个站点比较这些序列之间的差异。
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)