Как я могу разложить повторяющиеся измерения нескольких переменных в широкий формат?


Я пытаюсь взять столбцы, которые находятся в длинном формате, и распространить их на широкий формат, как показано ниже. Я хотел бы использовать tidyr, чтобы решить эту проблему с помощью инструментов обработки данных, в которые я инвестирую, но чтобы сделать этот ответ более общим, пожалуйста, предоставьте другие решения.

Вот что у меня есть:

library(dplyr); library(tidyr)

set.seed(10)
dat <- data_frame(
    Person = rep(c("greg", "sally", "sue"), each=2),
    Time = rep(c("Pre", "Post"), 3),
    Score1 = round(rnorm(6, mean = 80, sd=4), 0),
    Score2 = round(jitter(Score1, 15), 0),
    Score3 = 5 + (Score1 + Score2)/2
)

##   Person Time Score1 Score2 Score3
## 1   greg  Pre     80     78   84.0
## 2   greg Post     79     80   84.5
## 3  sally  Pre     75     74   79.5
## 4  sally Post     78     78   83.0
## 5    sue  Pre     81     78   84.5
## 6    sue Post     82     81   86.5

Желаемый широкий формат:

  Person Pre.Score1 Pre.Score2 Pre.Score3  Post.Score1 Post.Score2 Post.Score3
1   greg         80         78       84.0           79          80        84.5
2  sally         75         74       79.5           78          78        83.0
3    sue         81         78       84.5           82          81        86.5

Я могу сделать это, сделав что-то вроде этого для каждого счета:

spread(dat %>% select(Person, Time, Score1), Time, Score1) %>% 
    rename(Score1_Pre = Pre, Score1_Post = Post)

И затем с помощью _join, но это кажется многословным и как будто должно быть более эффективный способ.

Сопутствующие вопросы:
тидир от широкого до длинного с двумя повторными мерами
можно ли использовать разброс по нескольким столбцам в tidyr, подобный dcast?

3 47

3 ответа:

Если вы хотите придерживаться tidyr/dplyr

dat %>% 
  gather(temp, score, starts_with("Score")) %>% 
  unite(temp1, Time, temp, sep = ".") %>% 
  spread(temp1, score)

Используя reshape2:

library(reshape2)
dcast(melt(dat), Person ~ Time + variable)

Производит:

Using Person, Time as id variables
  Person Post_Score1 Post_Score2 Post_Score3 Pre_Score1 Pre_Score2 Pre_Score3
1   greg          79          78        83.5         83         81       87.0
2  sally          82          81        86.5         75         74       79.5
3    sue          78          78        83.0         82         79       85.5

Используя dcast из пакета data.table.

library(data.table)#v1.9.5+
dcast(setDT(dat), Person~Time, value.var=paste0("Score", 1:3))

Или reshape из baseR

reshape(as.data.frame(dat), idvar='Person', timevar='Time',direction='wide')