0

I want to calculate the number of days in each month with rainfall >= 2.5 mm for every column. I was able to calculate it for a single column after taking help from this post like

require(seas)
library (zoo)
data(mscdata)
dat.int <- (mksub(mscdata, id=1108447))

dat.int$yearmon <- as.yearmon(dat.int$date, "%b %y")
require(plyr)
rainydays_by_yearmon <- ddply(dat.int, .(yearmon), summarize, rainy_days=sum(rain >= 1.0) )
print.data.frame(rainydays_by_yearmon)

Now I want to apply it for all the columns. I have tried the following code

for(i in 1:length(dat.int)){
  y1 <- dat.int[[i]]
  rainydays <- ddply(dat.int, .(yearmon), summarize, rainy_days=sum(y1 >= 2.5))
  if(i==1){
    m1 <- rainydays
  }
  else{
    m1 <- cbind(rainydays, m1)
  }
  print(i)
}
m1

But I am unable to get the desired results. Please help me out!!!

UseR10085
  • 7,120
  • 3
  • 24
  • 54

2 Answers2

1

I would use dplyr and tidyr from tidyverse instead. pivot_longer puts the data into long form with is easier to manipulate. pivot_wider makes it wide again (probably unnecessary depending on your next step)

library(seas)
library(tidyverse)
library(zoo)
data(mscdata)
dat.int <- (mksub(mscdata, id=1108447))

dat.int %>% 
  as_tibble() %>% # for easier viewing 
  mutate(yearmon = as.yearmon(dat.int$date, "%b %y")) %>% 
  select(-date, -year, -yday) %>% 
  pivot_longer(cols = -yearmon, names_to = "variable", values_to = "value") %>% 
  group_by(yearmon, variable) %>% 
  summarise(rainy_days = sum(value > 2.5)) %>% 
  pivot_wider(names_from = "variable", values_from = "rainy_days")
Richard Telford
  • 9,558
  • 6
  • 38
  • 51
  • Running the code gives following error `Error in select(., -date, -year, -yday) : unused arguments (-date, -year, -yday)` – UseR10085 Mar 28 '20 at 04:34
  • I could able to solve the error. Actually, the select function is masked when we load the `seas` library. So, I have used `dplyr::select` and it solved the error. – UseR10085 Mar 28 '20 at 05:30
  • There is no `select` in `seas`, but there is in `MASS` and `raster`. Consider using the `conflicted` package to deal with conflicts – Richard Telford Mar 28 '20 at 17:00
0

if you don't mind using the data.table library, see the solution below.

library('data.table')
library('seas')
setDT(mscdata)
mscdata[id == 1108447 & rain >= 2.5, .(rain_ge_2.5mm = .N), 
        by = .(year, month = format(date, "%m"))]

Output

#    year month rain_ge_2.5mm
# 1: 1975    01            12
# 2: 1975    02             8
# 3: 1975    03            10
# 4: 1975    04             2
# 5: 1975    05             4
# ---                         
# 350: 2004    07           2
# 351: 2004    08           5
# 352: 2004    10          10
# 353: 2004    11          14
# 354: 2004    12          14

If you want to process all ids, then you can group data by id as below.

For rain only:

mscdata[, .(rain_ge_2.5mm = sum(rain >= 2.5)),
        by = .(id, year, month = format(date, "%m"))]

For rain, snow, and precip

mscdata[, .(rain_ge_2.5mm = sum(rain >= 2.5), 
            snow_ge_2 = sum(snow >= 2.0), 
            precip_ge_2 = sum(precip >= 2.0)),
        by = .(id, year, month = format(date, "%m"))]

#         id year month rain_ge_2.5mm snow_ge_2 precip_ge_2
# 1: 1096450 1975    01             1        10           9
# 2: 1096450 1975    02             0         5           3
# 3: 1096450 1975    03             1         9           9
# 4: 1096450 1975    04             1         2           3
# 5: 1096450 1975    05             5         1           6
# ---                                                       
# 862: 2100630 2000    07            NA        NA           3
# 863: 2100630 2000    08            NA        NA           8
# 864: 2100630 2000    09            NA        NA           6
# 865: 2100630 2000    11            NA        NA          NA
# 866: 2100630 2001    01            NA        NA          NA
Sathish
  • 12,453
  • 3
  • 41
  • 59