从宽到长:多列,两个时间点,两组
Wide to long: multiple columns, two timepoints, two groups
我已经搜索并找到了很多示例,到目前为止我还没有解决将我的数据从宽数据转换为长数据的问题。
以下是数据示例:
set.seed(12345)
id = 1:100
age = sample(1:100, 100, replace=TRUE)
group = sample(1:2, 100, replace=TRUE)
t0_var1 = sample(1:300, 100, replace=TRUE)
t2_var1 = sample(1:300, 100, replace=TRUE)
t0_var2 = sample(1:600, 100, replace=TRUE)
t2_var2 = sample(1:600, 100, replace=TRUE)
t0_var3 = sample(1:700, 100, replace=TRUE)
t2_var3 = sample(1:700, 100, replace=TRUE)
dataset = data.frame(id, age, group, t0_var1, t2_var1, t0_var2, t2_var2, t0_var3, t2_var3)
head(dataset)
id age group t0_var1 t2_var1 t0_var2 t2_var2 t0_var3 t2_var3
1 1 73 1 177 16 46 126 490 431
2 2 88 2 268 180 285 460 8 250
3 3 77 2 38 213 159 505 353 326
4 4 89 2 154 197 139 561 512 210
5 5 46 2 200 174 358 406 231 50
6 6 17 2 230 204 96 516 575 506
我需要按如下方式排列列:
id | age | group | assessment | var1 | var2 | var3
1 | 23 1 1 12 34 64
1 | 23 1 2 34 14 68
2 | 43 2 1 22 44 54
2 | 43 2 2 34 54 88
...
我尝试了不同的方法,但我一次只能设法转换两列。
预先感谢您的帮助。
来自 Ben 的评论:
pivot_longer(dataset, cols = -c(id, age, group), names_to = c("assessment", ".value"), names_pattern = "t(\d+)_(\w+)")
# A tibble: 200 x 7
id age group assessment var1 var2 var3
<int> <int> <int> <chr> <int> <int> <int>
1 1 14 1 0 287 1 280
2 1 14 1 2 266 5 523
3 2 51 2 0 136 456 444
4 2 51 2 2 66 292 260
5 3 80 1 0 111 263 635
6 3 80 1 2 275 255 70
7 4 90 1 0 174 438 212
8 4 90 1 2 161 161 694
9 5 92 1 0 86 184 595
10 5 92 1 2 176 399 32
正则表达式t(\d+)_(\w+)
表示:
- 查找 1 个或多个数字:字母“t”后的“\d+”。
- 那么应该有个下划线“_”
- 然后寻找1个或多个单词字符:"\w+"
- 现在检索“( )”所包含的部分
因此,此问题的 return 值将是“t”后面的数字(例如 0 或 2),然后是列名的后缀(例如 var1、var2、var3)
我们可以使用 melt
来自 data.table
library(data.table)
melt(setDT(dataset), measure = patterns("var1$", "var2$", "var3$"),
value.name = paste0("var", 1:3))
我已经搜索并找到了很多示例,到目前为止我还没有解决将我的数据从宽数据转换为长数据的问题。
以下是数据示例:
set.seed(12345)
id = 1:100
age = sample(1:100, 100, replace=TRUE)
group = sample(1:2, 100, replace=TRUE)
t0_var1 = sample(1:300, 100, replace=TRUE)
t2_var1 = sample(1:300, 100, replace=TRUE)
t0_var2 = sample(1:600, 100, replace=TRUE)
t2_var2 = sample(1:600, 100, replace=TRUE)
t0_var3 = sample(1:700, 100, replace=TRUE)
t2_var3 = sample(1:700, 100, replace=TRUE)
dataset = data.frame(id, age, group, t0_var1, t2_var1, t0_var2, t2_var2, t0_var3, t2_var3)
head(dataset)
id age group t0_var1 t2_var1 t0_var2 t2_var2 t0_var3 t2_var3
1 1 73 1 177 16 46 126 490 431
2 2 88 2 268 180 285 460 8 250
3 3 77 2 38 213 159 505 353 326
4 4 89 2 154 197 139 561 512 210
5 5 46 2 200 174 358 406 231 50
6 6 17 2 230 204 96 516 575 506
我需要按如下方式排列列:
id | age | group | assessment | var1 | var2 | var3
1 | 23 1 1 12 34 64
1 | 23 1 2 34 14 68
2 | 43 2 1 22 44 54
2 | 43 2 2 34 54 88
...
我尝试了不同的方法,但我一次只能设法转换两列。
预先感谢您的帮助。
来自 Ben 的评论:
pivot_longer(dataset, cols = -c(id, age, group), names_to = c("assessment", ".value"), names_pattern = "t(\d+)_(\w+)")
# A tibble: 200 x 7
id age group assessment var1 var2 var3
<int> <int> <int> <chr> <int> <int> <int>
1 1 14 1 0 287 1 280
2 1 14 1 2 266 5 523
3 2 51 2 0 136 456 444
4 2 51 2 2 66 292 260
5 3 80 1 0 111 263 635
6 3 80 1 2 275 255 70
7 4 90 1 0 174 438 212
8 4 90 1 2 161 161 694
9 5 92 1 0 86 184 595
10 5 92 1 2 176 399 32
正则表达式t(\d+)_(\w+)
表示:
- 查找 1 个或多个数字:字母“t”后的“\d+”。
- 那么应该有个下划线“_”
- 然后寻找1个或多个单词字符:"\w+"
- 现在检索“( )”所包含的部分
因此,此问题的 return 值将是“t”后面的数字(例如 0 或 2),然后是列名的后缀(例如 var1、var2、var3)
我们可以使用 melt
来自 data.table
library(data.table)
melt(setDT(dataset), measure = patterns("var1$", "var2$", "var3$"),
value.name = paste0("var", 1:3))