Dplyr在没有所有数据的情况下计算均值和方差

时间:2018-06-20 14:31:14

标签: r dplyr

我有一个开始如下的数据集:

set.seed(50)
n <- 20
s_num <- c(10,20,30)
counts <- c(0,1,2,3,4)

strata <- sample(s_num, n, replace=T)
sites <- seq(1, n, by=1)
observed <- sample(counts, n, replace=T)

df <- as.data.frame(cbind(strata,sites,observed))

我可以按层进行分组,并使用dplyr获取均值和方差:

library(dplyr)
df2 <- df %>%
  group_by(strata) %>%
  summarise(mcount = mean(observed),
            varcount = var(observed))

问题是数据库中不再有0个计数:

df3 <- subset(df,observed != 0)

因此,均值和方差现在是不正确的:

df4 <- df3 %>%
  group_by(strata) %>%
  summarise(mcount = mean(observed),
            varcount = var(observed))

但是我有站点数:

site_count <- df %>%
  group_by(strata) %>%
  summarise(count_plot = n_distinct(sites))

我是否仍可以使用dplyr计算没有0的平均方差?通过将站点计数合并到df,实际上并不算太难。变化比较困难。如果需要,我可以加回0行,但是如果可能的话,我想看看是否有一种简单的方法。谢谢。

3 个答案:

答案 0 :(得分:2)

您可以在管道中添加filter

df2 <- df %>%
 filter(observed != 0) %>%
 group_by(strata) %>%
 summarise(mcount = mean(observed),
          varcount = var(observed))

这样,您无需创建中间数据框。

答案 1 :(得分:1)

我们可以为子集创建逻辑条件

:visible

注意:不建议使用df %>% mutate(ind = observed != 0) %>% group_by(strata) %>% summarise(mcount = mean(observed[ind]), varcount = var(observed[ind])) # A tibble: 3 x 3 # strata mcount varcount # <dbl> <dbl> <dbl> #1 10 1.89 0.861 #2 20 1.6 0.8 #3 30 3 0.667 ,因为as.data.frame(cbind可以将其转换为cbind(矩阵只能容纳一个类),这将导致所有列matrixfactorcharacter(如果有任何字符列)。而是使用as.data.frame

答案 2 :(得分:1)

一旦计算出count_plot,就可以根据公式手动计算均值和方差。

方差计算为sum((x - mean(x))^2)/(length(x) - 1)

df3 %>% 
  left_join(site_count) %>% 
  group_by(strata) %>%
  summarise(N        = unique(count_plot),
            mcount   = sum(observed)/N,
            varcount = sum((observed - mcount)^2, (N - n())*mcount^2)/(N - 1)) %>% 
  select(-N)


# # A tibble: 3 x 3
#   strata mcount varcount
#    <dbl>  <dbl>    <dbl>
# 1   10.0   1.89    0.861
# 2   20.0   1.33    1.07 
# 3   30.0   2.40    2.30 

匹配df2

df2

# A tibble: 3 x 3
  strata mcount varcount
   <dbl>  <dbl>    <dbl>
1   10.0   1.89    0.861
2   20.0   1.33    1.07 
3   30.0   2.40    2.30