我有一个数据框,里面有日平均温度数据,结构如下:
Days_above = Site_Daily_average %>%
group_by(Year, Site) %>%
summarise("23" = sum(Temp > 23), "24" = sum(Temp > 24),"25"= sum(Temp >
25), "26"= sum(Temp > 26), "27"= sum(Temp > 27), "28"= sum(Temp > 28), "29"
= sum(Temp > 29),"30"= sum(Temp > 30), "31" = sum(Temp > 31), "ABOVE
THRESHOLD" = sum(Temp > maxthreshold))%>% as.data.frame()
我正在尝试生成一个汇总表,其中总计每个站点一年中的天数超过某些温度阈值,例如25c,26c。 我可以使用dplyr手动实现这一点,如so-
Year Site 23 24 25 26 27 28 29 30 31 ABOVE THRESHOLD
1 2012 EB 142 142 142 91 64 22 0 0 0 0
2 2012 FFCE 238 238 238 210 119 64 0 0 0 0
3 2012 IB 238 238 238 218 138 87 1 0 0 0
4 2013 EB 115 115 115 115 115 109 44 0 0 0
5 2013 FFCE 223 223 216 197 148 114 94 0 0 0
6 2013 IB 365 365 365 348 299 194 135 3 0 0
哪个产生如下表:
{{1}}
...
然而,正如您所看到的,代码相当冗长。我遇到的问题是为一系列温度阈值产生相同的输出,即Tempclasses = Seq(16,32,0.25)。
正如您所看到的那样,需要很长时间才能手动输入。我觉得这是一个非常简单的计算,应该有办法使用dplyr识别序列向量中的每个变量,执行此函数并以完整的表格格式生成输出。对不起,如果不清楚,因为我对R比较新, 任何建议都会受到欢迎,谢谢你。
答案 0 :(得分:3)
此处采用tidyverse
方法,同样使用mtcars
进行说明:
library(tidyverse)
mtcars %>%
mutate(threshold = cut(mpg,
breaks=seq(10, max(mtcars$mpg)+10, 5),
labels=seq(10, max(mtcars$mpg)+5, 5))) %>%
group_by(cyl, threshold) %>%
tally %>%
ungroup %>%
complete(threshold, nesting(cyl), fill=list(n=0)) %>%
arrange(desc(threshold)) %>%
group_by(cyl) %>%
mutate(N_above = cumsum(n)) %>%
select(-n) %>%
arrange(cyl, threshold)
threshold cyl N_above 1 10 4 11 2 15 4 11 3 20 4 11 4 25 4 6 5 30 4 4 6 35 4 0 7 10 6 7 8 15 6 7 9 20 6 3 10 25 6 0 11 30 6 0 12 35 6 0 13 10 8 14 14 15 8 8 15 20 8 0 16 25 8 0 17 30 8 0 18 35 8 0
如果您想要宽屏格式的最终数据,请在最后添加spread
并删除arrange
:
... %>%
select(-n) %>%
spread(threshold, N_above)
cyl 10 15 20 25 30 35 1 4 11 11 11 6 4 0 2 6 7 7 3 0 0 0 3 8 14 8 0 0 0 0
答案 1 :(得分:1)
正如@dww所述,我们可以使用cut
来获取所需的格式。我在mtcars
数据集上尝试过此操作,我们创建范围从10到35,mpg
列的步长为5。
df <- mtcars
df$group <- cut(df$mpg, seq(10, 35, 5))
然后我们按cyl
进行分组并使用table
来计算其中有多少属于相应存储桶的数量。
table(df$cyl, df$group)
# (10,15] (15,20] (20,25] (25,30] (30,35]
#4 0 0 5 2 4
#6 0 4 3 0 0
#8 6 8 0 0 0
现在,如果某个值大于10,它也大于15,因此(15,20)桶中的数字还应包括(10,15)桶中的数字和(20,15)桶中的数字应该包括以前的号码。因此,我们需要这个表的行式cumsum
t(apply(table(df$cyl, df$group), 1, cumsum))
# (10,15] (15,20] (20,25] (25,30] (30,35]
# 4 0 0 5 7 11
# 6 0 4 7 7 7
# 8 6 14 14 14 14
对于您的情况,代码将
Site_Daily_average$group <- cut(Site_Daily_average$Temp, seq(16,32,0.25))
#and then do table to get required answer.
t(apply(table(Site_Daily_average$Year,Site_Daily_average$Site,
Site_Daily_average$group), 1, cumsum)