使用tidyverse,在每个子集内的分布上有条件地求和值
问题描述:
我有一个示例数据框,其中记录了month
和precip
的每一天。使用tidyverse,在每个子集内的分布上有条件地求和值
set.seed(560)
df<-data.frame(month= rep(1:4, each=30),
precip= rep(c(rnorm(30, 20, 10), rnorm(30, 10, 2),
rnorm(30, 50, 1), rnorm(30, 15, 3))))
对于每个子集,我要计数实例的值是+/- 2个标准偏差(SD)的数量高于或低于该月的precip
值的平均值。本质上我需要在价值分布的极端(即分布的尾部)找到价值。这个结果栏将被称为count
。上面35.969个月1个值
set.seed(560)
output<-data.frame(month= rep(1:4, each=1), count= c(1,2,1,1))
通知和低于2.61的值是内+/-平均值的2SD:
输出将作为用于本实施例中的数据集显示如下。一个值(沉淀= 41.1)符合这个要求。证明:
sub1<- subset(df, month==1)
v1<- mean(sub1$precip)+ 2*sd(sub1$precip)#35.969
v2<- mean(sub1$precip)- 2*sd(sub1$precip)#2.61
sub2<- subset(df, month==2)
v3<- mean(sub2$precip)+ 2*sd(sub2$precip)#13.89
v4<- mean(sub2$precip)- 2*sd(sub2$precip)#7.35
sub3<- subset(df, month==3)
v5<- mean(sub3$precip)+ 2*sd(sub3$precip)#51.83
v6<- mean(sub3$precip)- 2*sd(sub3$precip)#48.308
sub4<- subset(df, month==4)
v7<- mean(sub4$precip)+ 2*sd(sub4$precip)#18.69
v8<- mean(sub4$precip)- 2*sd(sub4$precip)#9.39
我曾尝试:
output<-
df %>%
group_by(month)%>%
summarise(count= sum(precip > (mean(precip)+(2*sd(precip)))&
precip < (mean(precip)-(2*sd(precip))))))
答
在基础R
tapply(df$precip, df$month, function(a) sum(abs(scale(a)) >= 2))
输出
1 2 3 4
1 2 2 1
答
很简单的解决,你的逻辑和&
改变或|
一个在这两种情况下都不会有排。
output<-
df %>%
group_by(month)%>%
summarise(count= sum(precip > (mean(precip)+(2*sd(precip))) |
precip < (mean(precip)-(2*sd(precip)))))
output
# A tibble: 4 x 2
# month count
# <int> <int>
# 1 1 1
# 2 2 2
# 3 3 2
# 4 4 1
以及添加使用by
(配对至dplyr::group_by()
)
do.call(rbind,
by(df, df$month, FUN=function(i){
tmp <- i[i$precip < mean(i$precip) - 2*sd(i$precip) |
i$precip > mean(i$precip) + 2*sd(i$precip),]
return(data.frame(month=i$month[[1]], count=nrow(tmp)))
})
)
# month count
# 1 1 1
# 2 2 2
# 3 3 2
# 4 4 1
可选地一个基础R溶液中,用ave
,ifelse
和aggregate
:
df$count <- ifelse(df$precip > ave(df$precip, df$month, FUN=function(g) mean(g) + 2*sd(g)) |
df$precip < ave(df$precip, df$month, FUN=function(g) mean(g) - 2*sd(g)), 1, 0)
aggregate(count ~ month, df, FUN=sum)
# month count
# 1 1 1
# 2 2 2
# 3 3 2
# 4 4 1