在 R 中重新排列数据框 - 将唯一的重复值合并到行中

Rearrange Dataframe in R - Merging Unique Repeated Values into Rows

第一次问问题,如果我的格式不对,请见谅。

我已经在网上搜索了 3 天来找到这个问题的答案,但一直找不到任何东西。我有一个由 3 列组成的数据框:重复随机生成的参与者 ID(例如 W21334D0、B8123K)、问题编号(分类 - 例如 q1、q2、q3)和问题响应(数字和分类 - 例如, "1", "1,2", "15,20,15").

例如,我将始终获得的数据框的形式为:

Participant question_id question_answer
W21334D0 q1 1
W21334D0 q2 1,2
W21334D0 q3 0
W21334D0 q4 1
B8123K q3 1
B8123K q2 2,1
B8123K q4 0
P0213MEW q1 1
P0213MEW q3 0
P0213MEW q4 1
P0213MEW q2 1,2

我希望重新排列数据框或创建一个新的数据框,以便每个唯一的参与者 ID 都是一行,其中每个唯一的 question_id 是按 q1-q96 顺序排列的一列。

例如:

Participant q1 q2 q3 q4
W21334D0 1 1,2 0 1
B8123K NA 2,1 1 0
P0213MEW 1 1,2 0 1

在过去的几天里,我尝试了各种方法,最接近的是为每个独特的参与者创建单独的数据框,其中包括参与者行 question_ids 和 question_answers(但不按顺序)。

为此,我做了:

for(i in unique(dat$participant)) {
  nam <- paste(i)
  assign(nam, t(dat[dat$participant==i,-1]))
}

但是使用这段代码,我不知道如何将数据帧组合成一个数据帧,也不知道如何将行全部按“q1、q2、q3、q4 .. ."

如有任何帮助,我们将不胜感激!

reshape2

reshape2::dcast(dat, Participant ~ question_id, value.var = "question_answer")
#   Participant   q1  q2 q3 q4
# 1      B8123K <NA> 2,1  1  0
# 2    P0213MEW    1 1,2  0  1
# 3    W21334D0    1 1,2  0  1

(这也适用于 data.table 包,如果 dat 继承 data.table。)

dplyr

tidyr::pivot_wider(dat, Participant, names_from = "question_id", values_from = "question_answer")
# # A tibble: 3 x 5
#   Participant q1    q2    q3    q4   
#   <chr>       <chr> <chr> <chr> <chr>
# 1 W21334D0    1     1,2   0     1    
# 2 B8123K      <NA>  2,1   1     0    
# 3 P0213MEW    1     1,2   0     1    

数据

dat <- structure(list(Participant = c("W21334D0", "W21334D0", "W21334D0", "W21334D0", "B8123K", "B8123K", "B8123K", "P0213MEW", "P0213MEW", "P0213MEW", "P0213MEW"), question_id = c("q1", "q2", "q3", "q4", "q3", "q2", "q4", "q1", "q3", "q4", "q2"), question_answer = c("1", "1,2", "0", "1", "1", "2,1", "0", "1", "0", "1", "1,2")), class = "data.frame", row.names = c(NA, -11L))

您可以使用包 tidyr 中的 pivot_wider() 来实现该目标。 下面是示例数据:

dt <- data.frame("Participant" = sample(c("W21334D0", "B8123K", "P0213MEW"), 12, replace = T),
                 "question_id" = sample(paste0("q", 1:4), 12, replace = T),
                 "question_answer" = sample(rnorm(100, 1, 1), 12, replace = T))

library(tidyr)

dt %>% 
  pivot_wider(id_cols = "Participant", 
              names_from = "question_id", 
              values_from = "question_answer", 
              values_fn = mean)