суммирование температурных данных на основе вектора температурных порогов - PullRequest
0 голосов
/ 22 мая 2018

У меня есть фрейм данных со среднесуточными данными о температуре, структурированный примерно так:

 'data.frame':  4666 obs. of  6 variables:
 $ Site : chr  "EB" "FFCE" "IB" "FFCE" ...
 $ Date : Date, format: "2013-01-01" "2013-01-01" "2013-01-01" "2014-01-01" ... 
 $ Day  : int  1 1 1 1 1 1 1 1 1 1 ...
 $ Year : int  2013 2013 2013 2014 2014 2014 2014 2015 2015 2015 ...
 $ Month: int  1 1 1 1 1 1 1 1 1 1 ...
 $ Temp : num  28.5 28.3 28.3 27 27.8 ...

Я пытаюсь создать сводную таблицу, которая просто суммирует количество дней в году на сайт вышеопределенные температурные пороги, например 25c, 26c.я могу добиться этого вручную, используя dplyr как so-

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()  

, который создает таблицу примерно так:

   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

...

однако, как вы можетеувидеть код довольно многословно.Проблема, с которой я столкнулся, заключается в том, что я получаю такой же вывод для последовательности температурных порогов, то есть Tempclasses = Seq (16,32,0.25).

Как вы можете видеть, это заняло бы много времени, чтобы напечатать это вручную,я чувствую, что это очень простое вычисление, и должен быть способ использовать dplyr для распознавания каждой переменной в векторе последовательности, выполнения этой функции и получения выходных данных в полном формате таблицы.извините, если это неясно, так как я относительно новичок в R, любые предложения приветствуются, спасибо.

Ответы [ 2 ]

0 голосов
/ 22 мая 2018

Вот подход 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
0 голосов
/ 22 мая 2018

Как прокомментировал @dww, мы можем использовать cut, чтобы получить требуемый формат.Я пробовал это на mtcars наборе данных, где мы создаем диапазон от 10 до 35 с шагом 5 для столбца mpg.

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) ведро должно включать как предыдущее число.Следовательно, для этой таблицы нам понадобится построчная сумма

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...