1

我有两个 data.frames 看起来像:

df1
  Gene name   sample1    sample2    sample3     sample4     sample5  
   A             0          1         0           0           1 
   B             1          0         0           1           0
   C             0          0         1           1           1
   D             1          0         0           1           0



df_final
  Gene name   sample1    sample2    sample3     sample4     sample5  
   A             1          1         1           0           0 
   B             0          1         0           0           0
   C             1          1         0           0           0
   D             1          1         0           0           0

仅存在“0”和“1”值。我想要一个单独的 data.frame,其中当 df1 或 df2 中的条目在两个 data.frame 中 == 1 时,它将保持为“1”(与“0”相同)。否则,当它在一个 data.frame(例如 df1)中为 == 1 并且在另一个 data.frame(例如 df2)中为 0 时,条目将变为 1。这两个 data.frame 具有相同的行数并且列数相同。

所需的输出将是:

df1
  Gene name   sample1    sample2    sample3     sample4     sample5  
   A             1          1         1           0           1 
   B             1          1         0           1           0
   C             1          1         1           1           1
   D             1          1         0           1           0

由于我是 RI 的新手,我想在第一个和第二个 data.frame 上使用 for 循环来学习循环多个 data.frame。目前我无法做这样的工作。任何人都可以帮助我吗?

最好的,

E.

4

3 回答 3

3

您想要的是按位或运算:https ://en.wikipedia.org/wiki/Bitwise_operation#OR

R 3.0 中有用于按位运算的函数:bitwAnd、bitwNot、bitwOr、bitwShiftL、bitwShiftR 和 bitwXor(bitwOr 是您要查找的函数)。

joran 给出的答案可以正常工作,但如果您运行的是 R 3.0,我建议您使用按位运算,因为它们往往工作得更快:

 > system.time(for (i in 1:10000) {df3[,-1] <- ((df1[,-1] + df2[,-1]) > 0) + 0})
   user  system elapsed 
  13.58    0.00   13.59

 > system.time(for (i in 1:10000) {df3[,-1] = bitwOr(unlist(df1[,-1]), unlist(df2[,-1]))})
   user  system elapsed 
   5.44    0.00    5.45 
于 2013-05-07T22:21:48.077 回答
3

做这种事情的“R”方式是利用矢量化:

df3 <- df1
> df3[,-1] <- ((df1[,-1] + df2[,-1]) > 0) + 0
> df3
  Genename sample1 sample2 sample3 sample4 sample5
1        A       1       1       1       0       1
2        B       1       1       0       1       0
3        C       1       1       1       1       1
4        D       1       1       0       1       0

循环仍在发生,但在引擎盖下,编译的代码要快得多。

简要说明:

我们可以以向量化的方式添加两个数据帧的数字部分:

(df1[,-1] + df2[,-1])
  sample1 sample2 sample3 sample4 sample5
1       1       2       1       0       1
2       1       1       0       1       0
3       1       1       1       1       1
4       2       1       0       1       0

然后,如果我们询问哪些值大于零,我们会得到“正确”的答案,但使用布尔值而不是 0 和 1:

> (df1[,-1] + df2[,-1]) > 0
     sample1 sample2 sample3 sample4 sample5
[1,]    TRUE    TRUE    TRUE   FALSE    TRUE
[2,]    TRUE    TRUE   FALSE    TRUE   FALSE
[3,]    TRUE    TRUE    TRUE    TRUE    TRUE
[4,]    TRUE    TRUE   FALSE    TRUE   FALSE

幸运的是,如果我们简单地添加 0,R 会将布尔值强制转换为整数:

> ((df1[,-1] + df2[,-1]) > 0) + 0
     sample1 sample2 sample3 sample4 sample5
[1,]       1       1       1       0       1
[2,]       1       1       0       1       0
[3,]       1       1       1       1       1
[4,]       1       1       0       1       0
于 2013-05-07T19:10:03.347 回答
1

捷径:#df3 <- as.integer(df1+df2>0)#这是错误的

编辑捷径:df3 <- apply(df1+df2>0, c(1,2), as.integer)#there可能更短

使用循环等:

df3 <- as.data.frame(matrix(rep(NA, nrow(df1)*ncol(df1)),ncol=ncol(df1))
names(df3) <- names(df1)

for(i in 1:ncol(df1)){
  for(j in 1:nrow(df1)){
    if(i==1){#edited
       df3[j,i] <- df1[j,i]#edited; note, this is dangerous b/c it is assuming the data frames are organized in the same way
    }else{#edited
       df3[j,i] <- as.integer((df1[j,i] + df2[j,i])>0)
    }#edited
  }
}

那个工作?

于 2013-05-07T19:31:18.247 回答