我对R来说相对较新,我希望用更有说服力和更快速的东西取代我的凌乱循环(申请?)。基本上,我想基于其他矩阵中相同位置的值是否相互匹配来填充新矩阵。让我来说明一下:
>df1
V1 V2 V3
1 A G A
2 T T T
3 C A A
4 G C G
>df2
V1
1 A
2 T
3 C
4 G
>df3
V1 V2 V3
1 .25 .99 .41
2 .21 .25 .75
3 .35 .65 .55
4 .75 .21 .11
>newdf <- data.frame(matrix(ncol= ncol(df3), nrow = nrow(df3)))
请注意,df1和df3的尺寸始终相同,而df2将始终具有相同的nrow。
如果位置匹配:如果df1 [i,j] == df2 [i],那么我想要newdf [i,j] = df3 [i,j]
如果位置不匹配:如果df1 [i,j]!= df2 [i],那么我想要newdf [i,j] = 1-df3 [i,j]
例如df1 [1,2] =&#39; G&#39;和df2 [1] =&#39; A&#39;,所以我想要newdf [1,2] =(1- df3 [1,2])
我写了一个非常粗略的for循环来成功执行此操作:
df1<- as.matrix(df1)
df2<- as.matrix(df2)
df3<- as.matrix(df3)
newdf <- data.frame(matrix(ncol= ncol(df3), nrow = nrow(df3)))
for (i in (1:nrow(df1))){
for (j in (1:ncol(df1))){
if (df1[i,j] == df2[i]) {
newdf[i,j] = df3[i,j] }
else {
newdf[i,j] = 1- df3[i,j] }
}
}
这给了我想要的结果:
>newdf
X1 X2 X3
1 0.25 0.01 0.41
2 0.21 0.25 0.75
3 0.35 0.35 0.45
4 0.75 0.79 0.11
当我有大量数据时,这是一个非常缓慢而混乱的过程。有没有其他方法可以解决这个问题,也许使用申请系列?谢谢,抱歉讨厌的代码。
答案 0 :(得分:1)
您可以使用apply
创建不匹配的值的索引,然后只需从一个值中减去它们
idx <- (!apply(df1, 2, function(x) x == df2))
## alternatively, you can use x != df2 too
## idx <- (apply(df1, 2, function(x) x != df2))
df3[idx] <- 1 - df3[idx]
df3
# V1 V2 V3
# 1 0.25 0.01 0.41
# 2 0.21 0.25 0.75
# 3 0.35 0.35 0.45
# 4 0.75 0.79 0.11
根据apply
是否匹配df1
df2
给出的矩阵为TRUE / FALSE
V1 V2 V3
[1,] TRUE FALSE TRUE
[2,] TRUE TRUE TRUE
[3,] TRUE FALSE FALSE
[4,] TRUE FALSE TRUE
因此,使用!
取消否定会产生相反的值。
!apply(df1, 2, function(x) x == df2)
V1 V2 V3
[1,] FALSE TRUE FALSE
[2,] FALSE FALSE FALSE
[3,] FALSE TRUE TRUE
[4,] FALSE TRUE FALSE
然后告诉我们需要更改df
的哪些值
df3[idx]
[1] 0.01 0.35 0.79 0.45
另一种方法是让df2
与df1
df2 <- cbind(df2, rep( df2, ncol( df1 ) - 1))
df1 != df2