首页 > 解决方案 > 使用 tidyverse 重塑 data.frame 及其列名

问题描述

data.frame对每个样本的几个因素和测量值进行了一些实验。例如:

factors <- c("age","sex")

data.frame看起来像这样:

library(dplyr)
set.seed(1)
df <- do.call(rbind,lapply(1:10,function(i) expand.grid(age=c("Y","O"),sex=c("F","M")) %>% dplyr::mutate(val=rnorm(4))))
grouped.mean.val.df <- df %>% dplyr::group_by_(.dots=factors) %>% dplyr::summarise(mean.val=mean(val))

我想创建一个data.frame具有单行的列数是因子组合的数量(即nrow(expand.grid(age=c("Y","O"),sex=c("F","M"))在本例中),其中的值是mean df$val的对应组合factors

为了获得mean df$val我所做的每种因素组合:

grouped.mean.val.df <- df %>% dplyr::group_by_(.dots=factors) %>% dplyr::summarise(mean.val=mean(val))

data.frame我想得到的结果是:

res.df <- data.frame(Y.F=grouped.mean.val.df$mean.val[1],
                     Y.M=grouped.mean.val.df$mean.val[2],
                     O.F=grouped.mean.val.df$mean.val[3],
                     O.M=grouped.mean.val.df$mean.val[4])

有没有tidyverse办法得到它?

标签: rdataframedplyrtidyverse

解决方案


我们可以做unite然后一个spread. unite'age' 和 'sex' 创建单个列,mutatefactor(以使顺序与预期的相同)并执行spread'wide' 格式

library(tidyverse)
grouped.mean.val.df %>%
   unite(agesex, age, sex, sep=".") %>% 
   mutate(agesex = factor(agesex, levels = unique(agesex))) %>%
   spread(agesex, mean.val)
# A tibble: 1 x 4
#     Y.F   Y.M    O.F     O.M
#   <dbl> <dbl>  <dbl>   <dbl>
#1 0.0695 0.411 -0.118 0.00577

group_by_此外,我们可以使用group_by_at将字符串作为变量来代替

df %>%
     group_by_at(factors) %>%
     summarise(mean.val = mean(val)) %>%
     unite(agesex, age, sex, sep=".") %>% 
     mutate(agesex = factor(agesex, levels = unique(agesex))) %>%
     spread(agesex, mean.val)

推荐阅读