我目前有一个或多或少具有以下特征的数据集:
Country <- rep(c("Honduras", "Belize"),each=6)
Year <- rep(c(2010,2011,2012,2014,2015,2016),2)
Observation <- c(2, 5,NA, NA,2,3,NA, NA,2,3,1,NA)
df <- data.frame(Country, Year, Observation)
我想做的是找到一个命令/编写函数,该函数只用:填充每个国家的NA
如果NA观察是第一年(2010年(,则用下一个非NA观察填充;
如果NA观测是针对最后一年(2014年(的,则将其填入上一可用期间的观测。
3.1如果NA观测是在第一次和最后一次填充之间的年份,则是最近两个时期的平均值。
3.2然而,如果有2个或多个连续的NA,(以2个为例(首先用前面的观测值填充第一个,用与(3.1(相同的方法填充第二个
举例来说,以前的数据集最终应该是:
Observation2 <- c(2, 5, 5, 3.5 ,2,3,2, 2,2,3,1,1)
df2 <- data.frame(Country, Year, Observation2)
我希望我已经足够清楚了。这很具体,但我希望有人能帮忙。
如果你不理解,可以随意提出任何问题。
输入。有一个问题是,是否有意更改该问题下的评论中提到的国家名称以及最后的说明中所示的国家名称,但无论如何,假设每一个年份增加的子序列都是一个单独的组和组,即grp。(如果国家的前6个条目是洪都拉斯,最后6个是伯利兹,那么我们可以在下面的代码中用group_by(国家(替换group_by。(
问题澄清。我们假设问题是在集团内部提出的:
- 将用第一个非NA替换主要NA
- 后面的NA将替换为最后一个非NA
- 如果存在一个被非NA包围的连续NA,则将其替换为先前的非NA
- 如果存在两个连续的NA,则第一个用先前的非NA代替,第二个用先前非NA和下一个非NA的平均值填充
- 这个问题并没有解决3+个连续NA的情况,所以这可能永远不会发生,但只是在它发生的情况下,代码应该做的是用之前的非NA填充第一个NA,其余部分应该使用线性插值填充
代码。现在,对于每个组,将任何NA替换为先前的值。然后通过na.approx对剩余部分使用线性插值,使用rule=2扩展端点。最后只保留所需的列。
dplyr冲突。请注意,dplyr中的滞后和过滤器与基R中同名的函数以不兼容的方式冲突,因此我们将它们排除在外,如果我们想访问它们,则使用dplyr::前缀。
library(dplyr, exclude = c("lag", "filter"))
library(zoo)
df2 <- df %>%
# group_by(Country) %>%
group_by(grp = cumsum(c(TRUE, diff(Year) < 0))) %>%
mutate(Observation2 = coalesce(Observation, dplyr::lag(Observation)) %>%
na.approx(rule = 2)) %>%
ungroup %>%
select(Country, Year, Observation2)
identical(df2$Observation2, Observation2)
## [1] TRUE
备注
我们使用了这个问题中的输入。
Country <- rep(c("Honduras", "Belize"),6)
Year <- rep(c(2010,2011,2012,2014,2015,2016),2)
Observation <- c(2, 5,NA, NA,2,3,NA, NA,2,3,1,NA)
df <- data.frame(Country, Year, Observation)
df
给予:
Country Year Observation
1 Honduras 2010 2
2 Belize 2011 5
3 Honduras 2012 NA
4 Belize 2014 NA
5 Honduras 2015 2
6 Belize 2016 3
7 Honduras 2010 NA
8 Belize 2011 NA
9 Honduras 2012 2
10 Belize 2014 3
11 Honduras 2015 1
12 Belize 2016 NA
已添加
海报在评论中添加了另一个例子。我们在这里运行。这与上面第一段中讨论的简化为group_by的代码相同。(这不会改变结果。(
Country <- rep(c("Honduras", "Belize"),each=6)
Year <- rep(c(2010,2011,2012,2014,2015,2016),2)
Observation <- c(2, 5, NA, NA,2,3, NA, NA,2, NA,1,NA)
df <- data.frame(Country, Year, Observation)
df2 <- df %>%
group_by(Country) %>%
mutate(Observation2 = coalesce(Observation, dplyr::lag(Observation)) %>%
na.approx(rule = 2)) %>%
ungroup %>%
select(Country, Year, Observation2)
df2
给予:
# A tibble: 12 x 3
Country Year Observation2
<chr> <dbl> <dbl>
1 Honduras 2010 2
2 Honduras 2011 5
3 Honduras 2012 5
4 Honduras 2014 3.5
5 Honduras 2015 2
6 Honduras 2016 3
7 Belize 2010 2
8 Belize 2011 2
9 Belize 2012 2
10 Belize 2014 2
11 Belize 2015 1
12 Belize 2016 1