【问题标题】:Data frame from wide to long with multiple variables and ids R [duplicate]具有多个变量和ID R的从宽到长的数据框[重复]
【发布时间】:2018-11-14 15:26:20
【问题描述】:

我有一个数据框,其中包含参与者对两个文本的判断。假设每个文本都有一个正确答案和一个标识符,并且每个文本都被多次判断。

set.seed(123)
wide_df = data.frame('participant_id' = LETTERS[1:12]
                 , 'judgment_1' = round(rnorm(12)*100)
                 , 'correct_1' = round(rnorm(12)*100)
                 , 'text_id_1' = sample(1:12, 12, replace = F)
                 , 'judgment_2' = round(rnorm(12)*100)
                 , 'correct_2' = round(rnorm(12)*100)
                 , 'text_id_2' = sample(13:24, 12, replace = F)
                 )

这样:

   participant_id judgment_1 correct_1 text_id_1 judgment_2 correct_2 text_id_2
1               A        -56        40         4         43      -127        17
2               B        -23        11        10        -30       217        14
3               C        156       -56         1         90       121        22
4               D          7       179        12         88      -112        15
5               E         13        50         7         82       -40        13
...

我想将其转换为带有列的长格式:

participant_id   text_id   judgment   correct
             A         4        -56        40
             A        17         43       127     
...

我发现并遵循了 SO 建议 here:

wide_df %>% 
  gather(v, value, judgment_1:text_id_2) %>% 
  separate(v, c("var", "col")) %>% 
  arrange(participant_id) %>% 
  spread(col, value)

但是这种重塑方式会返回错误Error: Duplicate identifiers for rows (3, 6), (9, 12)

我认为我在概念上做了一些错误的事情,但找不到。我的错误在哪里?谢谢!

【问题讨论】:

  • 你能用decast试试吗:融化
  • 目前还不清楚您希望如何将 text_id_1 和 text_id_2 聚合为单个标识符“text_id”。与其他人类似。您是否想要另一个标识符为 1 或 2(称为“时间”),以便每个观察都有一个参与者 ID 和一个时间?
  • text_id_1text_id_2是属于判断1和2的标识符,所以可以是一个变量分别属于case作为判断和正确的。
  • 你为什么要收集judge_1和Text_id_2?而不是 Text_id_1 ?

标签: r reshape tidyr


【解决方案1】:

与我的其他答案相比,这是一种更动态的方式。这不需要手动合并所需的列,但确实依赖于列名模式。

wide_df %>% 
  gather(variable, value, -participant_id) %>% 
  mutate(
    variable = substr(variable, 1, nchar(variable)-2),
    rn = ave(1:length(participant_id), participant_id, variable, FUN = seq_along)
    ) %>% 
  spread(variable, value) %>% 
  select(-rn)

   participant_id correct judgment text_id
1               A      40      -56       4
2               A    -127       43      17
3               B      11      -23      10
4               B     217      -30      14
5               C     -56      156       1
6               C     121       90      22
7               D     179        7      12
8               D    -112       88      15
9               E      50       13       7
10              E     -40       82      13
11              F    -197      172      11
12              F     -47       69      19
13              G      70       46       9
14              G      78       55      24
15              H     -47     -127       2
16              H      -8       -6      20
17              I    -107      -69       8
18              I      25      -31      21
19              J     -22      -45       3
20              J      -3      -38      16
21              K    -103      122       5
22              K      -4      -69      23
23              L     -73       36       6
24              L     137      -21      18

【讨论】:

    【解决方案2】:

    答案已经存在:https://stackoverflow.com/a/12466668/2371031

    例如,

    set.seed(123)
    wide_df = data.frame('participant_id' = LETTERS[1:12]
                         , 'judgment_1' = round(rnorm(12)*100)
                         , 'correct_1' = round(rnorm(12)*100)
                         , 'text_id_1' = sample(1:12, 12, replace = F)
                         , 'judgment_2' = round(rnorm(12)*100)
                         , 'correct_2' = round(rnorm(12)*100)
                         , 'text_id_2' = sample(13:24, 12, replace = F)
    )
    
    dl <- reshape(data = wide_df, 
                  idvar = "participant_id", 
                  varying = list(judgment=c(2,5),correct=c(3,6),text_id=c(4,7)), 
                  direction="long", 
                  v.names = c("judgment","correct","text_id"),
                  sep="_")
    

    结果:

        participant_id time judgment correct text_id
    A.1              A    1      -56      40       4
    B.1              B    1      -23      11      10
    C.1              C    1      156     -56       1
    D.1              D    1        7     179      12
    E.1              E    1       13      50       7
    F.1              F    1      172    -197      11
    G.1              G    1       46      70       9
    H.1              H    1     -127     -47       2
    I.1              I    1      -69    -107       8
    J.1              J    1      -45     -22       3
    K.1              K    1      122    -103       5
    L.1              L    1       36     -73       6
    A.2              A    2       43    -127      17
    B.2              B    2      -30     217      14
    C.2              C    2       90     121      22
    D.2              D    2       88    -112      15
    E.2              E    2       82     -40      13
    F.2              F    2       69     -47      19
    G.2              G    2       55      78      24
    H.2              H    2       -6      -8      20
    I.2              I    2      -31      25      21
    J.2              J    2      -38      -3      16
    K.2              K    2      -69      -4      23
    L.2              L    2      -21     137      18
    

    【讨论】:

      【解决方案3】:

      有人在玩data.table

      library(data.table)
      superlong_df <- melt(wide_df, id.vars = "participant_id")
      setDT(superlong_df)[, `:=`(varn = gsub(".*_(\\d)", "\\1", variable),
                                 variable = gsub("_\\d$", "", variable))]
      dcast(superlong_df, participant_id + varn ~ variable)[, !"varn"]
      
          participant_id correct judgment text_id
       1:              A      40      -56       4
       2:              A    -127       43      17
       3:              B      11      -23      10
       4:              B     217      -30      14
       5:              C     -56      156       1
       6:              C     121       90      22
       7:              D     179        7      12
       8:              D    -112       88      15
       9:              E      50       13       7
      10:              E     -40       82      13
      11:              F    -197      172      11
      12:              F     -47       69      19
      13:              G      70       46       9
      14:              G      78       55      24
      15:              H     -47     -127       2
      16:              H      -8       -6      20
      17:              I    -107      -69       8
      18:              I      25      -31      21
      19:              J     -22      -45       3
      20:              J      -3      -38      16
      21:              K    -103      122       5
      22:              K      -4      -69      23
      23:              L     -73       36       6
      24:              L     137      -21      18
          participant_id correct judgment text_id
      

      【讨论】:

        【解决方案4】:

        这里是tidyr。基本上你会做unite() + separate_rows()unite 合并列,separate_rows 将它们排列成行 -

        wide_df %>% 
          unite(text_id, text_id_1, text_id_2) %>% 
          unite(judgment, judgment_1, judgment_2) %>% 
          unite(correct, correct_1, correct_2) %>% 
          separate_rows(2:4, sep = "_")
        
           participant_id judgment correct text_id
        1               A      -56      40       4
        2               A       43    -127      17
        3               B      -23      11      10
        4               B      -30     217      14
        5               C      156     -56       1
        6               C       90     121      22
        7               D        7     179      12
        8               D       88    -112      15
        9               E       13      50       7
        10              E       82     -40      13
        11              F      172    -197      11
        12              F       69     -47      19
        13              G       46      70       9
        14              G       55      78      24
        15              H     -127     -47       2
        16              H       -6      -8      20
        17              I      -69    -107       8
        18              I      -31      25      21
        19              J      -45     -22       3
        20              J      -38      -3      16
        21              K      122    -103       5
        22              K      -69      -4      23
        23              L       36     -73       6
        24              L      -21     137      18
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-02-17
          • 1970-01-01
          • 1970-01-01
          • 2021-10-23
          • 1970-01-01
          • 2020-07-12
          • 1970-01-01
          相关资源
          最近更新 更多