将宽数据转换为具有多个变量的长格式
这可能有一个简单的答案,但经过几个小时的搜索后,我仍然找不到它。基本上我需要将宽数据集转换为长格式数据集,但具有多个变量。我的数据集结构如下所示:
df1 <- data.frame(id = c(1,2,3),
sex = c("M","F","M"),
day0s = c(21,25,15),
day1s = c(20,30,18),
day2s = c(18,18,17),
day0t = c(2,5,7),
day1t = c(3,6,5),
day2t = c(3,8,7))
df1
id sex day0s day1s day2s day0t day1t day2t
1 M 21 20 18 2 3 3
2 F 25 30 18 5 6 8
3 M 15 18 17 7 5 7
基本上 3 个科目每天都做数学测试 (s) 和历史测试 (t),持续 3 天。我尝试使用 tidyr 中的 collect 将其转换为长格式,但我不知道如何将 mt 和 ht 变量分配给同一天。我还编写了一个新的变量 day,只有 day0 = 0、day1 = 1 和 day2 = 2。
dfl ?- df1 %?%
gather(day, value, - c(id,sex))
dfl
id sex variable value day
1 M day0s 21 0
1 M day1s 20 1
1 M day2s 18 2
1 M day0t 2 0
1 M day1t 3 1
1 M day2t 3 2
2 F day0s 25 0
2 F day1s 30 1
2 F day2s 18 2
2 F day0t 5 0
2 F day1t 6 1
2 F day2t 8 2
3 M day0s 15 0
3 M day1s 18 1
3 M day2s 17 2
3 M day0t 7 0
3 M day1t 5 1
3 M day2t 7 1
理想情况下,它最终应该是这样的。
id sex day s t
1 M 0 21 2
1 M 1 20 3
1 M 2 18 3
2 F 0 25 5
2 F 1 30 6
2 F 2 18 8
3 M 0 15 7
3 M 1 18 5
3 M 2 17 7
您对如何实现这一目标有什么建议吗?
回答
您可以pivot_longer在此处使用 {tidyr} 。
如果您的实际变量命名有点不同,您可以根据您的情况调整正则表达式。在这里,您可以尝试并相应地进行调整。(请注意,在 R 中必须转义反斜杠,因此在d+and 中使用双反斜杠w+)
一般来说,names_pattern参数的工作原理是将括号内的正则表达式与names_to参数匹配,因此这里:
(d+)-> 成为可变日。正则表达式d+匹配 1 个或多个数字。(w+)-> 变成“.value”。正则表达式w+匹配 1 个或多个单词字符。感谢r2evans指出了“.value”参数,从而避免了进一步的重塑。该文档指出.value“讲述pivot_longer(),该列名的一部分指定‘值’被测量(其将成为输出一个变量)”。虽然我没有完全理解文档解释,但结果是匹配的正则表达式被映射到输出数据中的变量名称。
library(dplyr)
library(tidyr)
df1 <- data.frame(id = c(1,2,3),
sex = c("M","F","M"),
day0mt = c(21,25,15),
day1mt = c(20,30,18),
day2mt = c(18,18,17),
day0ht = c(2,5,7),
day1ht = c(3,6,5),
day2ht = c(3,8,7))
df1
#> id sex day0mt day1mt day2mt day0ht day1ht day2ht
#> 1 1 M 21 20 18 2 3 3
#> 2 2 F 25 30 18 5 6 8
#> 3 3 M 15 18 17 7 5 7
df1 %>%
pivot_longer(cols = starts_with("day"),
names_pattern = "day(d+)(w+)",
names_to = c("day", ".value"))
#> # A tibble: 9 x 5
#> id sex day mt ht
#> <dbl> <chr> <chr> <dbl> <dbl>
#> 1 1 M 0 21 2
#> 2 1 M 1 20 3
#> 3 1 M 2 18 3
#> 4 2 F 0 25 5
#> 5 2 F 1 30 6
#> 6 2 F 2 18 8
#> 7 3 M 0 15 7
#> 8 3 M 1 18 5
#> 9 3 M 2 17 7
由reprex 包( v2.0.0 )于 2021 年 6 月 20 日创建
请注意,在较新版本的 tidyr 中,gather和spread被弃用并由pivot_longer和取代pivot_wider.
- Use `names_to = c("day", ".value")` and remove the `pivot_wider` 🙂