69

以下に示すように、長い形式の列をワイド形式に広げようとしています。私が投資しているデータ操作ツールでこれを解決するために 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 wide から long への 2 つの繰り返し
測定

4

4 に答える 4

85

編集: pivot_wider はしばらく前から存在し、この質問とコメントで問題に対処しているため、この回答を更新しています。今できること

pivot_wider(
    dat, 
    id_cols = 'Person', 
    names_from = 'Time', 
    values_from = c('Score1', 'Score2', 'Score3'), 
    names_glue = '{Time}.{.value}'
)

目的の結果を得るために。


元の答えは

dat %>% 
  gather(temp, score, starts_with("Score")) %>% 
  unite(temp1, Time, temp, sep = ".") %>% 
  spread(temp1, score)
于 2015-04-21T15:40:15.940 に答える
22

パッケージdcastからの使用。data.table

library(data.table)#v1.9.5+
dcast(setDT(dat), Person~Time, value.var=paste0("Score", 1:3))
#     Person Score1_Post Score1_Pre Score2_Post Score2_Pre Score3_Post Score3_Pre
#1:   greg          79         80          80         78        84.5       84.0
#2:  sally          78         75          78         74        83.0       79.5
#3:    sue          82         81          81         78        86.5       84.5

またはreshapeからbaseR

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

アップデート

開発版tidyr_0.8.3.9000またはCRANリリースから、複数の値の列にtidyr_1.0.0使用できますpivot_wider

library(tidyr)
library(stringr)
dat %>%
     pivot_wider(names_from = Time, values_from = str_c("Score", 1:3))
# A tibble: 3 x 7
#  Person Score1_Pre Score1_Post Score2_Pre Score2_Post Score3_Pre Score3_Post
#   <chr>       <dbl>       <dbl>      <dbl>       <dbl>      <dbl>       <dbl>
#1 greg           80          79         78          80       84          84.5
#2 sally          75          78         74          78       79.5        83  
#3 sue            81          82         78          81       84.5        86.5
于 2015-04-21T14:57:25.457 に答える