【问题标题】:Merge two binary data.frames according to values根据值合并两个二进制数据帧
【发布时间】:2013-05-07 18:59:41
【问题描述】:

我有两个 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.frames 中都是 == 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

由于我是 R 新手,我想在第一个和第二个 data.frame 上使用 for 循环 学习循环多个data.frames。目前我无法做这样的工作。 谁能帮帮我?

最好的,

E.

【问题讨论】:

  • 两个数据框的行数是否相同,每个基因一个?
  • 是的!相同的行数和相同的列数!我很快就会编辑!

标签: r


【解决方案1】:

做这种事情的“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

【讨论】:

  • 哦!只是一个简单的总和!极好的!非常感谢!
  • 伟大的乔兰,特别是解释!
【解决方案2】:

您想要的是按位或运算: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 

【讨论】:

  • 命令bitwOr从何而来?我从库bitops 知道bitOr,但是还有另一个包处理按位运算吗? (使用位操作+1,但我认为不需要unlist 命令...)
  • 它们在基本包中,但看起来它们在 R 3.0 中是新的(我之前没有注意到)。我不得不使用 unlist 因为该函数只接受向量作为参数,所以它不起作用。 stat.ethz.ch/R-manual/R-devel/library/base/html/bitwise.html
【解决方案3】:

快捷方式:#df3 &lt;- as.integer(df1+df2&gt;0) #这是错误的

编辑快捷方式:df3 &lt;- apply(df1+df2&gt;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
  }
}

那行吗?

【讨论】:

  • 是的!完美的!非常感谢!
  • 你的捷径有点误导人。正如 OP 所述,您不能简单地添加整个数据框。其中两列是字符,这将导致错误。此外,在这种情况下,as.integer 将删除维度,从而产生简单的向量,而不是数据框。
猜你喜欢
  • 2023-02-22
  • 1970-01-01
  • 2022-11-02
  • 2020-07-23
  • 1970-01-01
  • 1970-01-01
  • 2022-01-08
  • 2019-07-20
  • 2014-04-14
相关资源
最近更新 更多