我的问题在使用zoo::和data.table::之前已经得到了回答;我很好奇使用tidyverse/dplyr最好的解决方案是什么。
之前的答案(非潮汐):Forward and backward fill data frame in R Replacing NAs with latest non-NA value
我的数据如下所示,每个国家(美国、澳大利亚)的前两年(2015、2016)都有缺失的数据(底部的数据输入代码):
#> country year value
#> 1 usa 2015 NA
#> 2 usa 2016 NA
#> 3 usa 2017 100
#> 4 usa 2018 NA
#> 5 aus 2015 NA
#> 6 aus 2016 NA
#> 7 aus 2017 50
#> 8 aus 2018 60我想用2017年的可用值来填充每个国家/地区的缺失值。
我希望这个数字只能在2017年之前的几年内使用--所以2018年的安娜应该不会被任何东西所填充。它应该保持为NA。
所以我想要的输出是:
#> country year value
#> 1 usa 2015 100
#> 2 usa 2016 100
#> 3 usa 2017 100
#> 4 usa 2018 NA
#> 5 aus 2015 50
#> 6 aus 2016 50
#> 7 aus 2017 50
#> 8 aus 2018 60我尝试过group_by(country),然后我怀疑我应该使用coalesce(),但我通常会跨向量使用coalesce,而不是沿着它们。
library(tidyverse)
df %>% group_by(country) %>% 使用tidyverse工具做这件事最简单的方法是什么?
数据输入代码:
#install.packages("datapasta")
df <- data.frame(
stringsAsFactors = FALSE,
country = c("usa", "usa", "usa", "usa", "aus", "aus", "aus", "aus"),
year = c(2015L, 2016L, 2017L, 2018L, 2015L, 2016L, 2017L, 2018L),
value = c(NA, NA, 100L, NA, NA, NA, 50L, 60L)
)
df发布于 2020-03-05 15:54:55
我们可以在2017年之前为每个NA提供2017年的replace价值。
library(dplyr)
df %>%
group_by(country) %>%
mutate(value = replace(value, is.na(value) & year < 2017, value[year == 2017]))
#Similarly with ifelse
#mutate(value = ifelse(is.na(value) & year < 2017, value[year == 2017], value))
# country year value
# <chr> <int> <int>
#1 usa 2015 100
#2 usa 2016 100
#3 usa 2017 100
#4 usa 2018 NA
#5 aus 2015 50
#6 aus 2016 50
#7 aus 2017 50
#8 aus 2018 60发布于 2020-03-05 16:38:41
# Tidyverse solution
library(tidyverse)
df %>%
group_by(country) %>%
arrange(year) %>%
fill(value, .direction = 'up') %>%
ungroup() %>%
arrange(country, year)
# Base R solution:
data.frame(do.call("rbind", lapply(split(df, df$country), function(x){
x$value[which(is.na(x$value) & x$year < 2017)] <- x$value[which(x$year == 2017)]
return(x)
}
)
),
row.names = NULL
)https://stackoverflow.com/questions/60540499
复制相似问题