我正试图提取1950 - 2015年间每个年平均降雨量的几个测量站。降雨数据集由每日测量组成。
在计算每个站点的年平均值之前,我需要过滤数据,以便每个月必须有> 15天的数据。
怎么可以在R?
中完成让这成为一个有效的例子:
id<-rep(c("Station_1","Station_2","Station_3"),length(1),each=1080)
year<-rep(c(1950:1952),length(1:3),each=360)
month <- rep(c(1:12),length(1:9),each=30)
day <- rep(c(1:30),length(1:108))
value<-runif(3240, min=0, max=10)
df<-data.frame(cbind(id,year,month,day,value))
我尝试过类似的事情:
result<-df %>%
group_by(id,year,month) %>%
summarise(No._of_days=n(),mean_month=mean(value))
result<-result[!(result$No._of_days<15),]
result<-result %>%
group_by(id,year) %>%
summarise(No._of_months=n(),mean_year=mean(mean_month))
然而,这导致错误的解决方案,因为我正在采取“平均值”。
感谢您的任何建议。
答案 0 :(得分:1)
原始数据:在创建数据框时删除变量的默认因子分析。
df<-data.frame(id = id,year = year, month = month, day = day, value = value, stringsAsFactors = FALSE)
按id, year, month
对数据进行分组,并使用.N
内部变量获取子集的天数。接下来,链接结果(类似于dplyr中的%&gt;%)。现在分组id, year
,然后是条件N > 15
,最后计算该子集的mean
降雨量并存储在avg_rainfall
中。
setDT
通过引用将数据框转换为数据表
library("data.table")
setDT(df)[, .(value, .N), by = .(id, year, month)][N > 15, .(avg_rainfall = mean(value)), by = .(id, year)]
# id year avg_rainfall
# 1: Station_1 1950 4.852840
# 2: Station_1 1951 5.138069
# 3: Station_1 1952 4.934006
# 4: Station_2 1950 4.870335
# 5: Station_2 1951 5.179425
# 6: Station_2 1952 5.055026
# 7: Station_3 1950 4.959524
# 8: Station_3 1951 5.049996
# 9: Station_3 1952 4.927548
答案 1 :(得分:1)
一些事情,例如data.frame,由于你创建它的方式,将所有内容编码为一个因素。请改用:
df<-data.frame(id = id,
year = year,
month = month,
day = day,
value = value)
然后(我很抱歉,我不是magrittr
粉丝)以下内容将起作用:
# Filter into a new data.frame
df2 <- semi_join(df,
filter(summarise(group_by(df, year, month), N = n()), N > 15),
by = c(year = "year",
month = "month"))
# Summarise
summarise(group_by(df2, id),
value = mean(value, na.rm = TRUE))
答案 2 :(得分:0)
只关注代码,它适用于我,并进行了一些修改。例如。你写的是你想要的&gt; 15天的数据,但选择&gt; 14,也确保值是数字,而不是你的df中的因素。
`df<-data.frame(cbind(id,year,month,day,value))
df$value<- as.numeric(as.character(df$value))
result<-df %>%
group_by(id,year,month) %>%
summarise(No._of_days=n(),mean_month=mean(value))
result<-result[!(result$No._of_days<=15),]
result<-result %>%
group_by(id,year) %>%
summarise(No._of_months=n(),mean_year=mean(mean_month))`
代码放弃:从数学的角度来看,这种方法对我来说并不清楚。为什么要排除年度聚合少于16次测量的所有内容?如果您的测量结果确实是随机存在的,请考虑使用您在任何月份所拥有的值并在数据集中计算所有缺失的天数(例如,使用每个工作站的回归,年份(连续),日历周,之前和之后的降雨量)天)。
答案 3 :(得分:0)
使用dplyr
和magrittr
的方法略有不同:
library(dplyr)
set.seed(42) # this is only so we get consistent results to compare
# then generate id, year month, day, and value using your code
# but use what @NJBurgo used to generate df
df<-data.frame(id = id,
year = year,
month = month,
day = day,
value = value)
result <- df %>%
group_by(id,year,month) %>%
mutate(No._of_days=n()) %>%
filter(No._of_days > 15) %>% ## keep only rows with number of days greater than 15
ungroup() %>%
group_by(id,year) %>%
summarize(mean_year=mean(value))
# using set.seed(42), you should get
print(result)
## id year mean_year
## <fctr> <int> <dbl>
##1 Station_1 1950 4.954538
##2 Station_1 1951 4.878709
##3 Station_1 1952 4.737996
##4 Station_2 1950 4.942614
##5 Station_2 1951 4.876992
##6 Station_2 1952 5.193242
##7 Station_3 1950 5.235278
##8 Station_3 1951 4.955401
##9 Station_3 1952 4.905078
关键是filter
group_by
行(按id
,year
和month
分组)。我还使用mutate
代替summarise
来创建No._of_days
。然后ungroup()
,然后按id
和year
重新组合以计算均值。
30
天。
希望这有帮助。