来自列的calc mean / std / ci

时间:2015-07-16 22:10:13

标签: r statistics

是否有一个软件包可以轻松计算每个特定的n个数,即均值/ std / ci。 在示例中以数据开头:

> n = c(0,0,0,0,0,0,0,2,2,2,2,5,5,5,5,8,8,8,8)
> s = c(43,23,65,43,12,54,43,12,2,43,62,25,55,75,95,28,48,68,18)
> df = data.frame(n, s)
> df
   n  s
1  0 43
2  0 23
3  0 65
4  0 43
5  0 12
6  0 54
7  0 43
8  2 12
9  2  2
10 2 43
11 2 62
12 5 25
13 5 55
14 5 75
15 5 95
16 8 28
17 8 48
18 8 68
19 8 18

结果为:

data
n mean std ci
0 40   ..  ..
2 30   ..  ..
5 63   ..  ..
8 41   ..  ..

4 个答案:

答案 0 :(得分:3)

dplyr很好,但没有必要。在基地R:

 ## df() is built-in in R, avoid ...
 dd <- data.frame(n=rep(c(0,2,5,8),c(7,4,4,4)),
              s = c(43,23,65,43,12,54,43,12,2,43,
                  62,25,55,75,95,28,48,68,18))
 sumfun <- function(x) {
     m <- mean(x)
     s <- sd(x)
     se <- s/sqrt(length(x))
     c(mean=m,sd=s,lwr=m-1.96*se,upr=m+1.96*se)
 }

(或smean.cl.normal()包中的smean.cl.boot()Hmisc等等。)

 res <- do.call(rbind,tapply(dd$s,dd$n,sumfun))
 res <- cbind(n=unique(dd$n),as.data.frame(res))

或者@thelatemail指出:

 res <- do.call(data.frame,aggregate(s ~ n, data=df, FUN=sumfun ))

如果您定期使用它,可以轻松将其打包成一个功能。

对于较大的数据集/更复杂的转换,您可以搜索SO以查找比较dplyrplyrdata.tabledoBy包以及R解决方案使用tapply()ave()aggregate()by()的组合...

答案 1 :(得分:2)

您可以使用dplyr包。

这是一段代码片段。注意,我假设您希望使用95%级别的标准法线逼近来建立置信区间,但您可以做出您喜欢的任何选择。

n = c(0,0,0,0,0,0,0,2,2,2,2,5,5,5,5,8,8,8,8)
s = c(43,23,65,43,12,54,43,12,2,43,62,25,55,75,95,28,48,68,18)
df = data.frame(n, s)

  df %>%
  group_by(n) %>%
  summarise(mean = mean(s),
            std = sqrt(var(s)),
            lower = mean(s) - qnorm(.975)*std/sqrt(n()),
            upper = mean(s) + qnorm(.975)*std/sqrt(n()))

Source: local data frame [4 x 5]

  n     mean      std     lower    upper
1 0 40.42857 17.88721 27.177782 53.67936
2 2 29.75000 27.69326  2.611104 56.88890
3 5 62.50000 29.86079 33.236965 91.76303
4 8 40.50000 22.17356 18.770313 62.22969

答案 2 :(得分:0)

感谢大家的建议,我已经看了一下plyr并解决了它:

n = c(0,0,0,0,0,0,0,2,2,2,2,5,5,5,5,8,8,8,8)
s = c(43,23,65,43,12,54,43,12,2,43,62,25,55,75,95,28,48,68,18)
dd = data.frame(n, s)

library(plyr)
data <- ddply(dd,.(n),function(dd) c(mean=mean(dd$s),
                                    std = sd(dd$s),
                                    se = sd(dd$s)/sqrt(length(dd$s)),
                                    lower = mean(dd$s)-qnorm(.975)*sd(dd$s)/sqrt(length(dd$s)),
                                    upper = mean(dd$s)+qnorm(.975)*sd(dd$s)/sqrt(length(dd$s))
                                    ))

结果为:

    data
  n     mean      std        se     lower    upper
1 0 40.42857 17.88721  6.760731 27.177782 53.67936
2 2 29.75000 27.69326 13.846630  2.611104 56.88890
3 5 62.50000 29.86079 14.930394 33.236965 91.76303
4 8 40.50000 22.17356 11.086779 18.770313 62.22969

将来会避免使用df(),谢谢

答案 3 :(得分:0)

更新 tidyr 1.0.0

尽管@user1357015 的解决方案完全没问题,但如果你像我一样是 tidyverse 粉丝,还有一个优雅的选择:

新的 tidyr 1.0.0 包含一个没有引起太多关注但非常有用的函数:unnest_wider。 有了它,您可以将代码简化为以下内容:

df %>% 
  group_by(n) %>% 
  nest(data = -"n") %>% 
  mutate(ci = map(data, ~ MeanCI(.x$s))) %>% 
  unnest_wider(ci)

给出

# A tibble: 4 x 5
# Groups:   n [4]
      n data              mean lwr.ci upr.ci
  <dbl> <list>           <dbl>  <dbl>  <dbl>
1     0 <tibble [7 × 1]>  40.4  23.9    57.0
2     2 <tibble [4 × 1]>  29.8 -14.3    73.8
3     5 <tibble [4 × 1]>  62.5  15.0   110. 
4     8 <tibble [4 × 1]>  40.5   5.22   75.8