R:如何将具有重复变量(时间)的宽数据帧重新编码为长数据?
R: How to recode a wide data frame with repeating variables (time) into to long data?
我的数据框由数百人(行)组成,每个人回答 4 * 90 个项目。每个人在四个时间点回答相同的 90 个问题。每个人都属于两个组中的一个。我检查了这些组的测量不变性,这对于多组 SEM 和宽格式数据很容易。这是我的初始数据框的一个缩短的、可重现的例子:
df <- data.frame (ID = c(1,2,3,4,5),
Item1_time1 = c(4,4,5,4,3),
Item2_time1 = c(3,4,3,5,3),
Item1_time2 = c(5,4,4,5,4),
Item2_time2 = c(3,3,4,3,5),
group = c(0,1,0,1,0)
)
print(df)
ID Item1_time1 Item2_time1 Item1_time2 Item2_time2 group
1 1 4 3 5 3 0
2 2 4 4 4 3 1
3 3 5 3 4 4 0
4 4 4 5 5 3 1
5 5 3 3 4 5 0
但是,现在我想检查跨时间点的测量不变性。为此,所需的输出 应该如下所示:
ID time Item1 Item2 group
1 1 4 3 0
1 2 5 3 0
2 1 4 4 1
2 2 4 3 1
3 1 5 3 0
3 2 4 4 0
4 1 4 5 1
4 2 5 3 1
5 1 3 3 0
5 2 4 5 0
为了得到这个,我尝试将我最初的宽数据转换为长数据,但我并没有真正得到想要的输出:
library(data.table)
long <- melt(setDT(df), id.vars = c("ID"), variable.name = "time")
print(long)
ID time value
1: 1 Item1_time1 4
2: 2 Item1_time1 4
3: 3 Item1_time1 5
4: 4 Item1_time1 4
5: 5 Item1_time1 3
6: 1 Item2_time1 3
7: 2 Item2_time1 4
8: 3 Item2_time1 3
9: 4 Item2_time1 5
10: 5 Item2_time1 3
11: 1 Item1_time2 5
12: 2 Item1_time2 4
13: 3 Item1_time2 4
...
我如何编写“折叠”项目的代码,使它们不单独列出,而是每个都在其相应的时间类别中(参见上面的所需输出)?
我们可以使用 pivot_longer
和 names_pattern
从列名中捕获子字符串 ((...)
) 以创建 .value
列和 'time'专栏
library(tidyr)
pivot_longer(df, cols = -c(ID, group), names_to = c(".value", "time") ,
names_pattern = "(\w+)_\D+(\d+)")
-输出
# A tibble: 10 × 5
ID group time Item1 Item2
<dbl> <dbl> <chr> <dbl> <dbl>
1 1 0 1 4 3
2 1 0 2 5 3
3 2 1 1 4 4
4 2 1 2 4 3
5 3 0 1 5 3
6 3 0 2 4 4
7 4 1 1 4 5
8 4 1 2 5 3
9 5 0 1 3 3
10 5 0 2 4 5
(\w+)
- 捕获一个或多个字符,后跟列名称中的 _
,然后是任何 non-digits (\D+
),然后是第二次捕获一组一个或多个数字 ((\d+)
),对应于 .value
(列值),'time' 从列名称中获取数字后缀
像这样?
setDT(df)
result <- melt(df, measure.vars=patterns(Item1='Item1', Item2='Item2')
, variable.name = 'time')
setorder(result, ID, time, group)
result
## ID group time Item1 Item2
## 1: 1 0 1 4 3
## 2: 1 0 2 5 3
## 3: 2 1 1 4 4
## 4: 2 1 2 4 3
## 5: 3 0 1 5 3
## 6: 3 0 2 4 4
## 7: 4 1 1 4 5
## 8: 4 1 2 5 3
## 9: 5 0 1 3 3
## 10: 5 0 2 4 5
我的数据框由数百人(行)组成,每个人回答 4 * 90 个项目。每个人在四个时间点回答相同的 90 个问题。每个人都属于两个组中的一个。我检查了这些组的测量不变性,这对于多组 SEM 和宽格式数据很容易。这是我的初始数据框的一个缩短的、可重现的例子:
df <- data.frame (ID = c(1,2,3,4,5),
Item1_time1 = c(4,4,5,4,3),
Item2_time1 = c(3,4,3,5,3),
Item1_time2 = c(5,4,4,5,4),
Item2_time2 = c(3,3,4,3,5),
group = c(0,1,0,1,0)
)
print(df)
ID Item1_time1 Item2_time1 Item1_time2 Item2_time2 group
1 1 4 3 5 3 0
2 2 4 4 4 3 1
3 3 5 3 4 4 0
4 4 4 5 5 3 1
5 5 3 3 4 5 0
但是,现在我想检查跨时间点的测量不变性。为此,所需的输出 应该如下所示:
ID time Item1 Item2 group
1 1 4 3 0
1 2 5 3 0
2 1 4 4 1
2 2 4 3 1
3 1 5 3 0
3 2 4 4 0
4 1 4 5 1
4 2 5 3 1
5 1 3 3 0
5 2 4 5 0
为了得到这个,我尝试将我最初的宽数据转换为长数据,但我并没有真正得到想要的输出:
library(data.table)
long <- melt(setDT(df), id.vars = c("ID"), variable.name = "time")
print(long)
ID time value
1: 1 Item1_time1 4
2: 2 Item1_time1 4
3: 3 Item1_time1 5
4: 4 Item1_time1 4
5: 5 Item1_time1 3
6: 1 Item2_time1 3
7: 2 Item2_time1 4
8: 3 Item2_time1 3
9: 4 Item2_time1 5
10: 5 Item2_time1 3
11: 1 Item1_time2 5
12: 2 Item1_time2 4
13: 3 Item1_time2 4
...
我如何编写“折叠”项目的代码,使它们不单独列出,而是每个都在其相应的时间类别中(参见上面的所需输出)?
我们可以使用 pivot_longer
和 names_pattern
从列名中捕获子字符串 ((...)
) 以创建 .value
列和 'time'专栏
library(tidyr)
pivot_longer(df, cols = -c(ID, group), names_to = c(".value", "time") ,
names_pattern = "(\w+)_\D+(\d+)")
-输出
# A tibble: 10 × 5
ID group time Item1 Item2
<dbl> <dbl> <chr> <dbl> <dbl>
1 1 0 1 4 3
2 1 0 2 5 3
3 2 1 1 4 4
4 2 1 2 4 3
5 3 0 1 5 3
6 3 0 2 4 4
7 4 1 1 4 5
8 4 1 2 5 3
9 5 0 1 3 3
10 5 0 2 4 5
(\w+)
- 捕获一个或多个字符,后跟列名称中的 _
,然后是任何 non-digits (\D+
),然后是第二次捕获一组一个或多个数字 ((\d+)
),对应于 .value
(列值),'time' 从列名称中获取数字后缀
像这样?
setDT(df)
result <- melt(df, measure.vars=patterns(Item1='Item1', Item2='Item2')
, variable.name = 'time')
setorder(result, ID, time, group)
result
## ID group time Item1 Item2
## 1: 1 0 1 4 3
## 2: 1 0 2 5 3
## 3: 2 1 1 4 4
## 4: 2 1 2 4 3
## 5: 3 0 1 5 3
## 6: 3 0 2 4 4
## 7: 4 1 1 4 5
## 8: 4 1 2 5 3
## 9: 5 0 1 3 3
## 10: 5 0 2 4 5