Длинные к широким данным с tidyR?

У меня есть данные, которые выглядят примерно так.

df = data.frame(name=c("A","A","B","B"),
                group=c("g1","g2","g1","g2"),
                V1=c(10,40,20,30),
                V2=c(6,3,1,7))

Я хочу изменить его так:

df = data.frame(name=c("A", "B"),               
                V1.g1=c(10,20),
                V1.g2=c(40,30),
                V2.g1=c(6,1),
                V2.g2=c(3,7))

Можно ли это сделать с помощью tidyR?

Я могу сделать это с изменением формы

reshape(df, idvar='name', timevar='group', direction='wide')

но всегда хорошо учиться чему-то новому.

Ответ 1

Код reshape является компактным, поскольку он работает для столбцов с несколькими значениями. Используя то же самое в tidyr, может потребоваться несколько шагов. Преобразуйте "широкий" формат в "длинный" с помощью gather, чтобы был один столбец "Val", unite столбцы "Var" (от предыдущего шага) и "group", чтобы создать единый "VarG", а затем используйте spread, чтобы преобразовать формат 'long' в 'wide'.

 library(tidyr)
 gather(df, Var, Val, V1:V2) %>% 
                    unite(VarG, Var, group) %>% 
                    spread(VarG, Val)
 #    name V1_g1 V1_g2 V2_g1 V2_g2
 #1    A    10    40     6     3
 #2    B    20    30     1     7

Ответ 2

dcast в data.table v1.9.5 + может обрабатывать несколько столбцов value.var. Таким образом, мы можем сделать:

require(data.table) # v1.9.5+
dcast(setDT(df), name ~ group, value.var=c("V1", "V2"))
#    name V1_g1 V1_g2 V2_g1 V2_g2
# 1:    A    10    40     6     3
# 2:    B    20    30     1     7

В принципе, нет необходимости плавить и отливать, а не просто бросать. Вы можете установить его, выполнив эти инструкции.