总结基于温度阈值矢量的温度数据

时间:2018-05-22 02:00:33

标签: r dplyr

我有一个数据框,里面有日平均温度数据,结构如下:

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比较新, 任何建议都会受到欢迎,谢谢你。

2 个答案:

答案 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)