首页 > 解决方案 > 如何根据测量时间以长格式组织代码

问题描述

我有一个关于将数据帧从宽格式转换为长格式的问题。我还没有找到任何适合我的数据框的解决方案。我们使用相同的问卷(例如 PANAS 和另外两份问卷)进行了三个测量时隙。我的数据框现在看起来像这样:

| code| PANAS_1| PANAS_2| PANAS1_1| PANAS1_2| PANAS2_1| PANAS2_2|

|CAPQ |   4    |    3   |    1    |   5     |    2    |    4   |

|BANI |   2    |    3   |    4    |   4     |    3    |    2   |

我想把它变成这样的格式:

| code| timeslot| PANAS_1| PANAS_2 | 

|CAPQ |   1     |    4   |    3    |   
|CAPQ |   2     |    1   |    5    |  
|CAPQ |   3     |    2   |    4    | 
  
|BANI |   1     |    2   |    3    |  
|BANI |   2     |    4   |    4    |   
|BANI |   3     |    3   |    2    |  

我试过melt()了,但我只是不知道该怎么做,因为问卷的变量名称不一样(第一个时间段中的变量名称是纯“PANAS_1”,第二个时间段中的变量以a开头1“PANAS1_1”和第三个时间段中的那些以 2“PANAS2_1) 开头。除此之外,我没有变量可以解释这些项目的时间段条件。

我希望你能理解我的问题并帮助我解决这个问题。如果您需要更多信息,请告诉我。

标签: rformat

解决方案


这是一种使用tidyverse. 您可以使用pivot_longer输入长格式,并将下划线后面的最后一个数字分开。然后,您可以timeslot为每个code/number 组合添加一个变量,假设时间是按顺序排列的。最后,您可以恢复为宽格式pivot_wider(或保留原样以进行进一步处理/分析)。

library(tidyverse)

df %>%
  pivot_longer(cols = -code, names_to = c("var", "PANAS"), names_sep = "_") %>%
  group_by(code, PANAS) %>%
  mutate(timeslot = 1:n()) %>%
  pivot_wider(id_cols = c(code, timeslot), names_from = PANAS, names_prefix = "PANAS_", values_from = value)

输出

  code  timeslot PANAS_1 PANAS_2
  <chr>    <int>   <dbl>   <dbl>
1 CAPQ         1       4       3
2 CAPQ         2       1       5
3 CAPQ         3       2       4
4 BANI         1       2       3
5 BANI         2       4       4
6 BANI         3       3       2

或者,您可以重命名列名并在其中明确包含时间:

names(df) <- c("code", paste("PANAS", rep(1:3, each = 2), rep(1:2, times = 3), sep = "_"))

df %>%
  pivot_longer(cols = -code, names_to = c("timeslot", "PANAS"), names_pattern = "PANAS_(\\d+)_(\\d+)") %>%
  pivot_wider(id_cols = c(code, timeslot), names_from = PANAS, names_prefix = "PANAS_", values_from = value)

推荐阅读