我有一个看起来像这样的数据框
+---------+--------+--------+--------+-------+
| 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")
答案 0 :(得分:3)
您可以使用data.table
melt
:
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现在也接受一个字符/整数向量列表 熔化成多个柱 - 即熔化成多于一个值 列同时。使用函数模式提供多个 图案很方便。参见示例部分
答案 1 :(得分:0)
使用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