首页 > 解决方案 > 长短data.frame格式之间的转换

问题描述

简单(?)tidyr问题:

我有一个data.frame长格式的有几个分组列和几个值列。我想将其转换为短(宽)格式,其中key将是分组列之一,并且结果data.frame将为所有其他分组列和每个值列的每个组合都有一个列。

这是我的长格式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))

这就是我希望得到的宽格式data.frame

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)

标签: rdataframedplyrtidyr

解决方案


我们可以使用gather转换为“长”格式,然后unite将列一起转换spread为“宽”

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

推荐阅读