【问题标题】:R: Convert multiple columns into single column [duplicate]R:将多列转换为单列[重复]
【发布时间】:2016-06-11 04:26:07
【问题描述】:

我有一个看起来像这样的数据框

+---------+--------+--------+--------+-------+
|   ID    | week1_t| week1_a| week2_t|week2_a|
+---------+--------+--------+--------+-------+
|    1    | 12     | 22     |  17    |   4   |
|    1    | 15     | 32     |  18    |   5   |
|    1    | 24     | 12     |  29    |   6   |
|    2    | 45     | 11     |  19    |   8   |
|    2    | 23     | 33     |  20    |   10  |
+---------+--------+--------+--------+-------+

有 48 列(第 1 周 - 第 24 周),带有“t”和“a”后缀。我想将所有周列合并为一个“周”列,如下所示:

+---------+--------+--------+--------
|   ID    | week   |  t     |  a    |
+---------+--------+--------+--------
|    1    | 1     | 22      |  17   |
|    1    | 2     | 32      |  18   |
|    1    | 3     | 12      |  19   | 
|    1    | 5     | 33      |  20   | 
+---------+--------+--------+-------

如何在 R 中进行这种转换?我想不出在多个 if 语句和 for 循环之外执行此操作的方法。

数据

dd <- read.table(header = TRUE, text = "ID week1_t week1_a  week2_t week2_a
  1      12      22       17       4   
  1      15      32       18       5   
  1      24      12       29       6   
  2      45      11       19       8   
  2      23      33       20      10")

【问题讨论】:

  • Package dplyr 具有您需要的所有功能。这是一个方便的备忘单:rstudio.com/wp-content/uploads/2015/02/…
  • 请展示您的尝试。并且不要使用那种表格格式。
  • reshape(dd, dir = 'long', varying = lapply(c('t','a'), grep, names(dd)), timevar = 'week')

标签: r


【解决方案1】:

你可以使用data.tablemelt:

library(data.table)
setDT(dd)
melt(dd, id = 1, measure=patterns("_t$", "_a$"), value.name = c("t", "a"), 
     variable.name = "week")

    ID week  t  a
 1:  1    1 12 22
 2:  1    1 15 32
 3:  1    1 24 12
 4:  2    1 45 11
 5:  2    1 23 33
 6:  1    2 17  4
 7:  1    2 18  5
 8:  1    2 29  6
 9:  2    2 19  8
10:  2    2 20 10

你可以从?melt读到:

measure.vars 现在也接受字符/整数向量列表 融为多个列 - 即融为多个值 同时列。使用函数模式提供多个 图案方便。请参阅示例部分

【讨论】:

  • 不敢相信这么简单...
【解决方案2】:

与tidyr/dplyr:

library(dplyr)
library(tidyr)

       # add row index so later spreading indexed correctly
dd %>% add_rownames() %>% 
    # melt to long format
    gather(week, value, -ID, -rowname) %>% 
    # separate week number from variable suffix
    separate(week, c('week', 'var')) %>% 
    # reduce week number to actual number
    mutate(week = extract_numeric(week)) %>% 
    # spread a and t values back to wide form
    spread(var, value) %>% 
    # clean up
    select(-rowname)

# Source: local data frame [10 x 4]
# 
#       ID  week     a     t
#    (int) (dbl) (int) (int)
# 1      1     1    22    12
# 2      1     2     4    17
# 3      1     1    32    15
# 4      1     2     5    18
# 5      1     1    12    24
# 6      1     2     6    29
# 7      2     1    11    45
# 8      2     2     8    19
# 9      2     1    33    23
# 10     2     2    10    20

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-22
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 2019-02-17
    • 1970-01-01
    • 2020-11-22
    相关资源
    最近更新 更多