【问题标题】:How to rbind when only some of the columns match当只有某些列匹配时如何进行 rbind
【发布时间】:2015-04-02 07:21:22
【问题描述】:

我有大约 18 个数据帧,它们本质上是存储在 Rptnames 列中的元素的频率计数。它们在 Rptnames 列中都有一些不同和相同的元素,所以它们看起来像这样

名为 GroupedTableProportiondelAll 的数据框

Rptname    freq

bob         4324234
jane        433
ham        4324
tim         22

dataframe called GroupedTableProportiondelLUAD

Rptname     freq

bob          987
jane         223
jonny        12
jim          98092

我正在尝试设置一个表格,以便 Rptname 成为列,而每一行都是频率。这样我就可以组合所有的数据帧。

我已经尝试了以下

   GroupedTableProportiondelAll_T <- as.data.frame(t(GroupedTableProportiondelAll))
    GroupedTableProportiondelLUAD_T <- as.data.frame(t(GroupedTableProportiondelLUAD))

   total <- rbind(GroupedTableProportiondelLUAD_T, GroupedTableProportiondelAll_T)

但我得到了错误 rbind(deparse.level, ...) 中的错误: 参数的列数不匹配

所以问题是 a) 我怎么能做 rbind(我想 cbind 也可以不用转置),这样绑定就可以在不需要匹配的情况下发生。
b)在这里合并会更好 c) 有没有办法为空值输入零 d) P'raps 有更好的方法来做到这一点,比如我不太熟悉的矩阵?我知道它的 4 个问题,但中心问题是相同的 - 当并非所有行或列都匹配时如何绑定

【问题讨论】:

  • 您应该将数据保留为长格式。这意味着您应该使用 data.frame ID 和 rbind 为每个 data.frame 添加一列。如果您坚持使用宽格式,则可以在之后使用 reshape2 包中的dcast,尽管这通常会使数据更难处理。
  • 也就是说我应该合并?这会用零填充空值吗?
  • 我在哪里提到了merge?我想你可以使用它...

标签: r


【解决方案1】:

rbind + dcast 技术的替代方案,将使用 tidyverse。

使用管道 (%&gt;%) 首先使用 bind_rows() 将所有数据帧绑定在一起,同时创建一个数据帧 id 列(在这种情况下,我只是将变量称为“df”)。然后使用spread() 将唯一的“Rptname”值移动为列名,并将“freq”的值传播到新列中。在这种情况下,“Rptname”是键,“freq”是值。

看起来像这样:

输入:

GTP_A
Rptname    freq
1     bob 4324234
2    jane     433
3     ham    4324
4     tim      22

GTP_LUAD
Rptname  freq
1     bob   987
2    jane   223
3   jonny    12
4     jim 98092

代码:

GroupTable <- bind_rows(GTP_A,GTP_LUAD, .id = "df") %>%
  spread(Rptname, freq)

输出:

GroupTable
df     bob  ham jane   jim jonny tim
1  1 4324234 4324  433    NA    NA  22
2  2     987   NA  223 98092    12  NA

更新: 截至 2019 年 9 月 13 日发布 tidyr 1.0.0 时,spread()gather() 已停用并分别由 pivot_wider()pivot_longer() 取代。 the release notes Hadley Wickem 表示“spread()gather() 不会消失,但它们已经退役,这意味着它们不再处于积极开发中。”

为了获得与上述相同的输出,您现在需要首先通过 Rptname 使用arrange(),然后使用pivot_wider()。如果你不先安排,你会得到类似的输出,但列顺序与spread()的输出不同。

GroupTable <- bind_rows(GTP_A, GTP_LUAD, .id = "df") %>%
  arrange(Rptname) %>% 
  pivot_wider(names_from = Rptname, values_from = freq)

【讨论】:

    【解决方案2】:

    您可以先rbind 添加一列来标识data.frame,然后再添加data.frame。然后使用reshape2包中的dcast函数。

    rpt1
    ##   Rptname    freq   df
    ## 1     bob 4324234 rpt1
    ## 2    jane     433 rpt1
    ## 3     ham    4324 rpt1
    ## 4     tim      22 rpt1
    
    rpt2
    ##   Rptname  freq   df
    ## 1     bob   987 rpt2
    ## 2    jane   223 rpt2
    ## 3   jonny    12 rpt2
    ## 4     jim 98092 rpt2
    
    
    rpt1$df <- "rpt1"
    rpt2$df <- "rpt2"
    rpt <- rbind(rpt1, rpt2)
    dcast(data = rpt, df ~ Rptname, value.var = "freq")
    ##     df     bob  ham jane tim   jim jonny
    ## 1 rpt1 4324234 4324  433  22    NA    NA
    ## 2 rpt2     987   NA  223  NA 98092    12
    

    【讨论】:

    • 由于他们有很多 data.frames,他们应该将它们放在一个列表中并执行类似 DFlist &lt;- Map(cbind, DFlist, g = seq_along(DFlist)); DF &lt;- do.call(rbind, DFlist) 的操作。
    猜你喜欢
    • 1970-01-01
    • 2020-09-06
    • 2011-07-02
    • 1970-01-01
    • 2011-09-14
    • 1970-01-01
    • 2021-05-01
    • 2013-06-02
    • 2012-03-29
    相关资源
    最近更新 更多