如果我有一个从2011年到2018年的时间序列数据框架。我怎样才能做一个for循环,分别计算每年的NA数量,如果特定年份的NA数量超过x %,我就放弃该年份或做一些事情。
请参考图片,看看我的数据框是什么样子的。
https://i.stack.imgur.com/2fwDk.png
years_values <- 2011:2020
years = pretty(years_values,n=10)
count = 0
for (y in years){
for (j in df$Flow == y) {
if (is.na(df$Flow[j]){
count = count+1
}
}
if (count) > 1{
bfi = BFI(df$Flow == y)}
else {bfi = NA}
}
我正在尝试使用这个代码来循环每年,然后计算NA。如果NA大于1%,我就不计算BFI,如果小于1%,就不计算BFI。我的BFI功能运行良好。我遇到的问题是如何形成这个循环。
由于您没有包含任何可重复的数据,所以让我们举一个简单的示例来捕获您自己的数据的本质。我们有一列Year
和一列Flow
,其中包含一些缺失值:
df <- data.frame(Year = rep(2011:2013, each = 4),
Flow = c(1, 2, NA, NA, 5, 6, NA, 8, 9, 10, 11, 12))
df
#> Year Flow
#> 1 2011 1
#> 2 2011 2
#> 3 2011 NA
#> 4 2011 NA
#> 5 2012 5
#> 6 2012 6
#> 7 2012 NA
#> 8 2012 8
#> 9 2013 9
#> 10 2013 10
#> 11 2013 11
#> 12 2013 12
现在假设我们想要计算每年缺失值的数量。我们可以像这样使用table
和is.na
:
tab <- table(df$Year, is.na(df$Flow))
tab
#>
#> FALSE TRUE
#> 2011 2 2
#> 2012 3 1
#> 2013 4 0
我们可以看到这些是缺失值的绝对计数,但我们可以通过将第二列除以该表的行和来将其转换为比例:
props <- tab[,2] / rowSums(tab)
props
#> 2011 2012 2013
#> 0.50 0.25 0.00
现在,假设我们想要找到并删除丢失病例超过33%的年份。我们可以只过滤大于0.33的props
值,并获得相关的年份(或年份):
years_to_drop <- names(props)[props > 0.33]
years_to_drop
#> [1] "2011"
现在我们可以使用它从原始数据帧中删除丢失值超过33%的年份:
df[!df$Year %in% years_to_drop,]
#> Year Flow
#> 5 2012 5
#> 6 2012 6
#> 7 2012 NA
#> 8 2012 8
#> 9 2013 9
#> 10 2013 10
#> 11 2013 11
#> 12 2013 12
创建于2022-11-14与reprex v2.0.2
正如Allan Cameron所建议的那样,没有必要使用循环,R通常在矢量上工作更有效。
我建议一个基于ave
的解决方案(使用前一个答案的合成数据)
df$NA_fraction <- ave(df$Flow, df$Year, FUN = (values) mean(is.na(values)))
df
Year Flow NA_fraction
1 2011 1 0.50
2 2011 2 0.50
3 2011 NA 0.50
4 2011 NA 0.50
5 2012 5 0.25
6 2012 6 0.25
7 2012 NA 0.25
8 2012 8 0.25
9 2013 9 0.00
10 2013 10 0.00
11 2013 11 0.00
12 2013 12 0.00
然后你可以选择任何阈值并通过它进行过滤
> df[df$NA_fraction < 0.3,]
Year Flow NA_fraction
5 2012 5 0.25
6 2012 6 0.25
7 2012 NA 0.25
8 2012 8 0.25
9 2013 9 0.00
10 2013 10 0.00
11 2013 11 0.00
12 2013 12 0.00