2016-05-20 2 views
0
obs pre.data1 post.data1 pre.data2 post.data2 pre.data3 post.data3 
1 0.40 0.12 0.61 0.15 0.58 0.06 
2 0.21 0.05 0.18 0.49 0.35 0.24 
3 0.48 0.85 0.00 0.62 0.96 0.37 
4 0.66 0.29 0.88 0.56 0.13 0.72 
5 0.43 0.23 0.80 0.78 0.05 0.90 
6 0.86 0.04 0.25 0.34 0.99 0.79 
7 0.57 0.86 0.20 0.34 0.11 0.34 
8 0.13 0.39 0.24 0.51 0.79 0.63 
9 0.87 0.57 0.00 0.55 0.86 0.72 

Я приложил пример моего набора данных выше.Сбор с тидиром от широкоформатного формата до начала названия колонки

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

obs key data1 data2 data3 
1 pre  0.50 0.26 0.12 
1 post 0.18 0.50 0.42 
2 pre  0.06 0.07 0.47 
2 post 0.98 0.87 0.89 
3 pre  0.34 0.55 0.72 
3 post 0.26 0.99 0.71 
4 pre  0.64 0.80 0.54 
4 post 0.01 0.36 0.38 

Я довольно новыми для R, но я знаю, он использует функцию сбора, но я знаком только с собирать с 2 колонки, как показано на многих руководство. Есть ли простой способ сделать это? Спасибо

+0

Пожалуйста, обратите внимание, чтобы принять лучшее решение, нажав на галочку рядом с голосованием – akrun

ответ

3

Мы можем сделать это легко с data.table, что и melt в data.table (для преобразования «широкий» до «» длинного формата) может занять несколько patterns для measure колонн.

library(data.table) 
dM <- melt(setDT(df1), measure = patterns("data1$", "data2", "data3"), 
    value.name = c('data1', 'data2', 'data3'), variable.name = 'key') 
dM[, key:= unique(sub("\\..*", "", names(df1)[-1]))[key]] 
dM[order(obs)] 
# obs key data1 data2 data3 
# 1: 1 pre 0.40 0.61 0.58 
# 2: 1 post 0.12 0.15 0.06 
# 3: 2 pre 0.21 0.18 0.35 
# 4: 2 post 0.05 0.49 0.24 
# 5: 3 pre 0.48 0.00 0.96 
# 6: 3 post 0.85 0.62 0.37 
# 7: 4 pre 0.66 0.88 0.13 
# 8: 4 post 0.29 0.56 0.72 
# 9: 5 pre 0.43 0.80 0.05 
#10: 5 post 0.23 0.78 0.90 
#11: 6 pre 0.86 0.25 0.99 
#12: 6 post 0.04 0.34 0.79 
#13: 7 pre 0.57 0.20 0.11 
#14: 7 post 0.86 0.34 0.34 
#15: 8 pre 0.13 0.24 0.79 
#16: 8 post 0.39 0.51 0.63 
#17: 9 pre 0.87 0.00 0.86 
#18: 9 post 0.57 0.55 0.72 

Или с помощью tidyr, мы преобразуем в «длинных» формате с gather, то separate колонка «вар» и «ключ» и «Переменная2' и spread его в„формате широкой“.

library(dplyr) 
library(tidyr) 
gather(df1, Var, Val, -obs) %>% 
     separate(Var, into = c("key", "Var2")) %>% 
     mutate(key = factor(key, levels = c("pre", "post"))) %>% 
     spread(Var2, Val) 
# obs key data1 data2 data3 
#1 1 pre 0.40 0.61 0.58 
#2 1 post 0.12 0.15 0.06 
#3 2 pre 0.21 0.18 0.35 
#4 2 post 0.05 0.49 0.24 
#5 3 pre 0.48 0.00 0.96 
#6 3 post 0.85 0.62 0.37 
#7 4 pre 0.66 0.88 0.13 
#8 4 post 0.29 0.56 0.72 
#9 5 pre 0.43 0.80 0.05 
#10 5 post 0.23 0.78 0.90 
#11 6 pre 0.86 0.25 0.99 
#12 6 post 0.04 0.34 0.79 
#13 7 pre 0.57 0.20 0.11 
#14 7 post 0.86 0.34 0.34 
#15 8 pre 0.13 0.24 0.79 
#16 8 post 0.39 0.51 0.63 
#17 9 pre 0.87 0.00 0.86 
#18 9 post 0.57 0.55 0.72 

Это можно также сделать с помощью reshape из base R (хотя, возможно, потребуется некоторая постобработка, чтобы сделать его аккуратным)

reshape(df1, idvar="obs", varying = list(2:3, 4:5, 6:7), direction="long") 
3

В tidyr:

# melt to long form 
df %>% gather(var, val, -obs) %>% 
    # separate into key and test labels 
    separate(var, c('key', 'var')) %>% 
    # spread to wide form 
    spread(var, val) %>% 
    # make it pretty so pre is before post for each obs 
    arrange(obs, desc(key)) 

# obs key data1 data2 data3 
# 1 1 pre 0.40 0.61 0.58 
# 2 1 post 0.12 0.15 0.06 
# 3 2 pre 0.21 0.18 0.35 
# 4 2 post 0.05 0.49 0.24 
# 5 3 pre 0.48 0.00 0.96 
# 6 3 post 0.85 0.62 0.37 
# 7 4 pre 0.66 0.88 0.13 
# 8 4 post 0.29 0.56 0.72 
# 9 5 pre 0.43 0.80 0.05 
# 10 5 post 0.23 0.78 0.90 
# 11 6 pre 0.86 0.25 0.99 
# 12 6 post 0.04 0.34 0.79 
# 13 7 pre 0.57 0.20 0.11 
# 14 7 post 0.86 0.34 0.34 
# 15 8 pre 0.13 0.24 0.79 
# 16 8 post 0.39 0.51 0.63 
# 17 9 pre 0.87 0.00 0.86 
# 18 9 post 0.57 0.55 0.72 
Смежные вопросы