dan
dan

Reputation: 6304

Converting between long and short data.frame formats

Simple (?) tidyr question:

I have a data.frame which has several grouping columns and several value columns, in long format. I want to convert it to short (wide) format, where the key would be one of the grouping columns and the resulting data.frame would have a column for each combination of all the other grouping columns and each of the value columns.

Here's my long-format data.frame:

set.seed(1)
library(dplyr)
df <- data.frame(treatment = rep(c(rep("T1",3),rep("T2",3)),2),
                 species = c(rep("S1",6),rep("S2",6)),
                 group = rep(LETTERS[1:3],4),
                 n = as.integer(runif(12,10,20))) %>%
  dplyr::group_by(treatment,species) %>% dplyr::mutate(freq = n/sum(n))

And here's what I want the resulting wide-format data.frame to be:

res.df <- data.frame(group = LETTERS[1:3],
                     T1.S1.n = dplyr::filter(df,treatment == "T1",species == "S1")$n,
                     T1.S1.freq = dplyr::filter(df,treatment == "T1",species == "S1")$freq,
                     T2.S1.n = dplyr::filter(df,treatment == "T2",species == "S1")$n,
                     T2.S1.freq = dplyr::filter(df,treatment == "T2",species == "S1")$freq,
                     T1.S2.n = dplyr::filter(df,treatment == "T1",species == "S2")$n,
                     T1.S2.freq = dplyr::filter(df,treatment == "T1",species == "S2")$freq,
                     T2.S2.n = dplyr::filter(df,treatment == "T2",species == "S2")$n,
                     T2.S2.freq = dplyr::filter(df,treatment == "T2",species == "S2")$freq)

Upvotes: 1

Views: 122

Answers (1)

akrun
akrun

Reputation: 887068

We could use gather to convert to 'long' format, then unite the columns together and spread to 'wide'

library(tidyverse)
gather(df, key, val, n:freq) %>% 
     unite(trtsp, treatment, species, key, sep = ".") %>%
     spread(trtsp, val)

Upvotes: 1

Related Questions