有条件地删除R

时间:2016-07-28 13:56:32

标签: r nested row mean

我正试图提取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))

然而,这导致错误的解决方案,因为我正在采取“平均值”。

感谢您的任何建议。

4 个答案:

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

使用dplyrmagrittr的方法略有不同:

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行(按idyearmonth分组)。我还使用mutate代替summarise来创建No._of_days。然后ungroup(),然后按idyear重新组合以计算均值。

顺便说一句,您的测试用例不足以对此进行测试,因为所有月份都有30天。

希望这有帮助。