【问题标题】:gather multiple times at once [duplicate]一次收集多次[重复]
【发布时间】:2016-01-01 06:30:48
【问题描述】:

假设我有一个像这样的data.frame dat

id       X_a      X_b       Y_a      Y_b
v1 -0.012758 0.004537 -0.022725 0.005833
v2 -0.016706 0.003332 -0.006948 0.004965
v3 -0.005629 0.006972 -0.010578 0.006069

我希望它变得“聚集”。请注意,X_aX_b 以及 Y_aY_b 应被收集。期望的结果是:

id    X_Y_type         X         Y
v1       X_Y_a -0.012758 -0.022725
v2       X_Y_a -0.016706 -0.006948
v3       X_Y_a -0.005629 -0.010578
v1       X_Y_b  0.004537  0.005833
v2       X_Y_b  0.003332  0.004965
v3       X_Y_b  0.006972  0.006069

gather()申请了两次不是我想要的:

dat %>%
  gather(X_type, X, X_a:X_b) %>%
  gather(Y_type, Y, Y_a:Y_b)

id X_type      X Y_type         Y
v1 X_a -0.012758    Y_a -0.022725
v2 X_a -0.016706    Y_a -0.006948
v3 X_a -0.005629    Y_a -0.010578
v1 X_b  0.004537    Y_a -0.022725
v2 X_b  0.003332    Y_a -0.006948
v3 X_b  0.006972    Y_a -0.010578
v1 X_a -0.012758    Y_b  0.005833
v2 X_a -0.016706    Y_b  0.004965
v3 X_a -0.005629    Y_b  0.006069
v1 X_b  0.004537    Y_b  0.005833
v2 X_b  0.003332    Y_b  0.004965
v3 X_b  0.006972    Y_b  0.006069

我想要 X_aY_aX_bY_b 的匹配,所以会是假语法

dat %>%
  gather(X_type = Y_type, list(X, Y), list(X_a:X_b, Y_a:Y_b))

有什么提示吗?

【问题讨论】:

    标签: r reshape2 tidyr


    【解决方案1】:

    使用dplyr/tidyr,一个选项是gather/spread。我们使用 key/value 参数中除 'id' 列、separate 'key' 列之外的所有列将 'wide' 转换为 'long' 格式,并将其从 'long' 重塑为 wide' 之一拆分列和'val',mutate'X_Y_type' 列由pasteing 子字符串'X_Y_',并用`arrange 更改order

    library(dplyr)
    library(tidyr)
    gather(dat, key, val, -id) %>% 
           separate(key, into=c('var1', 'X_Y_type')) %>%
           spread(var1, val) %>% 
           mutate(X_Y_type= paste0('X_Y_', X_Y_type)) %>%
           arrange(X_Y_type)
    #  id X_Y_type         X         Y
    #1 v1    X_Y_a -0.012758 -0.022725
    #2 v2    X_Y_a -0.016706 -0.006948
    #3 v3    X_Y_a -0.005629 -0.010578
    #4 v1    X_Y_b  0.004537  0.005833
    #5 v2    X_Y_b  0.003332  0.004965
    #6 v3    X_Y_b  0.006972  0.006069
    

    但是,这可以通过来自data.tablemelt 来完成。它可以在measure 参数中使用多个patterns 来将“宽”格式转换为“长”格式。

    library(data.table)#v1.9.6+
    DT <- melt(setDT(dat), measure=patterns('^X', '^Y'), 
              value.name=c('X', 'Y'), variable.name='X_Y_type')
    

    如果需要,可以使用paste 将“X_Y_type”列值更改为预期输出。

    DT[, X_Y_type := paste(names(DT)[2],
          unique(sub('.*_','', names(dat)[-1])), sep="_")[X_Y_type]]
    
    DT
    #   id   X_Y_type         X         Y
    #1: v1 X_Y_type_a -0.012758 -0.022725
    #2: v2 X_Y_type_a -0.016706 -0.006948
    #3: v3 X_Y_type_a -0.005629 -0.010578
    #4: v1 X_Y_type_b  0.004537  0.005833
    #5: v2 X_Y_type_b  0.003332  0.004965
    #6: v3 X_Y_type_b  0.006972  0.006069
    

    或者使用来自base Rreshape

    reshape(dat, idvar='id', varying=2:ncol(dat), sep="_", direction='long')
    

    【讨论】:

    • 谢谢。不幸的是,v1.9.6 在其他地方破坏了我的代码。
    • @Helix123 在这种情况下,您可以使用reshape from base R
    • @Helix123 更新为gather/spread 选项
    • @Helix123,它破坏了什么?你能报告这样的事情,这样他们就可以解决了。。
    • 感谢您对解决方案的概述!在这种情况下确实使用base::reshape 以避免另一个依赖项。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多