2016-12-26 80 views
0

我正在分组数据集上工作,我想将4个统计数据添加为4个新列:count,mean,ci lower,ci upper。如何使用返回不同数量的返回值的不同函数汇总分组数据?

我总结的意思,C1低,CI上限如下:

library(Hmisc) 
library(dplyr) 

# summarize count, mean, confidence intervals and make four new columns; 
mtcars %>% group_by(vs, am) %>% 
    do(
     as.data.frame(as.list(smean.cl.normal(.$mpg))) 
    ) 
#  vs am  Mean Lower Upper 
# <dbl> <dbl> <dbl> <dbl> <dbl> 
# 1  0  0 15.05000 13.28723 16.81277 
# 2  0  1 19.75000 15.54295 23.95705 
# 3  1  0 20.74286 18.45750 23.02822 
# 4  1  1 28.37143 23.97129 32.77157 

然而,当我添加数,新列变为列表2列:

df <- mtcars %>% group_by(vs, am) %>% 
    do(
     n = length(.$mpg), 
     stats = smean.cl.normal(.$mpg) 
    ) 

# # A tibble: 4 × 4 
#  vs am   n  stats 
# * <dbl> <dbl> <list> <list> 
# 1  0  0 <int [1]> <dbl [3]> 
# 2  0  1 <int [1]> <dbl [3]> 
# 3  1  0 <int [1]> <dbl [3]> 
# 4  1  1 <int [1]> <dbl [3]> 

我所需的输出是:

#  vs am  n  Mean Lower Upper 
# <dbl> <dbl> <int> <dbl> <dbl> <dbl> 
# 1  0  0 12 15.05000 13.28723 16.81277 
# 2  0  1  6 19.75000 15.54295 23.95705 
# 3  1  0  7 20.74286 18.45750 23.02822 
# 4  1  1  7 28.37143 23.97129 32.77157 

我应该怎么做到这一点呢?

在此先感谢。


我也试过:

mtcars %>% group_by(vs, am) %>% 
    do(
     as.data.frame(as.list(c(length(.$mpg), smean.cl.normal(.$mpg)))) 
    ) 

# Source: local data frame [4 x 8] 
# Groups: vs, am [4] 
# 
# vs am X12  Mean Lower Upper X6 X7 
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 
# 1  0  0 12 15.05000 13.28723 16.81277 NA NA 
# 2  0  1 NA 19.75000 15.54295 23.95705  6 NA 
# 3  1  0 NA 20.74286 18.45750 23.02822 NA  7 
# 4  1  1 NA 28.37143 23.97129 32.77157 NA  7 

这给了奇怪的结果。

+3

那么为什么你在第二次尝试时没有把它包装到'data.frame'中呢?为什么你认为它应该突然没有它的工作?我认为你可以简单地用'c'将它加上'mtcars%>%group_by(vs,am)%>%do(as.data.frame(as.list(c(n = length(。$ mpg) ,smean.cl.normal(。$ mpg)))))',no? –

+0

@DavidArenburg我也尝试了类似的办法:'mtcars%>%GROUP_BY(VS,上午)%>% 做( as.data.frame(as.list(C(长度($ MPG),smean.cl。 .normal(。$ mpg)))) )'。这给出了带有“NA”的奇怪列。所以我认为这是行不通的。为什么我没有'n ='得到奇怪的结果? – mt1022

+1

因为dplyr是试图将智能和做一些像'paste0(“X”,长度($ MPG))'为一组,因此,'数据赋予它一个新的名字。框架“每次添加一个新的列新名称 –

回答

1

您可以使用多个tidyverse包,即tidyrdplyrpurrrbroom做到这一点不do

这背后的原因是,do will eventually be replaced by purrr

它的作用:

  1. 组用vs和我
  2. 巢mpg格式到一个列表框。
  3. 创建统计列和n列作为列表框。
  4. 将列表框放入单独的行和列中。
  5. 删除数据列表框。

你需要做一些finagling得到适当形式的smean.cl.normal在第3步我的方法是变换输出到一个整洁的数据帧与broom::tidy然后tidyr::spread行成列。它对于每个vs/am组都是适当的整齐形式。这种方法可能可以改进,并希望这些建议将发表在评论中。

library(Hmisc) 
library(tidyverse) 

mtcars %>% 
    group_by(vs, am) %>% 
    nest(mpg) %>% 
    mutate(stats = map(data, ~spread(tidy(smean.cl.normal(.x$mpg)), names, x)), 
     n = map(data, nrow)) %>% 
    unnest(stats, n) %>% 
    select(-data) 
+0

嗨,感谢您更新的Tidyverse方式。为什么'df <- mtcars %>%group_by(vs,am)%>% ( n =长度(。$ mpg), stats = smean.cl.normal(。$ mpg) )%>%unnest(stats,n )'不起作用?是一个嵌套的列(它看起来像一列列表)不同于'unnest'列表的列吗? – mt1022

+0

由于行号的不同,你会分别对每个行为进行总结,然后总结出do方法。 –