这个问题在这里已经有了答案:
Replace missing values (NA) with most recent non-NA by group
(7 个回答)
5年前关闭。
我有一个 DF 个人,其中包含一些不完整和重复的特征,如下所示:
name <- c("A", "A", "B", "B", "B", "C", "D", "D")
age <- c(28,NA,NA,NA,NA,NA,53,NA)
birthplace <- c("city1",NA, "city2",NA,NA,NA,NA,NA)
value <- 100:107
df <- data.frame(name,age,birthplace,value)
name age birthplace value
1 A 28 city1 100
2 A NA <NA> 101
3 B NA city2 102
4 B NA <NA> 103
5 B NA <NA> 104
6 C NA <NA> 105
7 D 53 <NA> 106
8 D NA <NA> 107
由于该值对于行是唯一的。我想用这样的人的详细信息完成每一行:
name age birthplace value
1 A 28 city1 100
2 A 28 city1 101
3 B NA city2 102
4 B NA city2 103
5 B NA city2 104
6 C NA <NA> 105
7 D 53 <NA> 106
8 D 53 <NA> 107
我试着用
library(zoo)
library(dplyr)
df <- df %>% group_by(name) %>% na.locf(na.rm=F)
但效果不是很好。按组实现功能的任何想法?
最佳答案
作为另一个基本的 R 解决方案,这是一个穷人的 na.locf
fill_down <- function(v) {
if (length(v) > 1) {
keep <- c(TRUE, !is.na(v[-1]))
v[keep][cumsum(keep)]
} else v
}
要按组填写,方法是使用
tapply()
拆分并应用于每个组,以及 split<-
将组组合到原始几何体,如fill_down_by_group <- function(v, grp) {
## original 'by hand':
## split(v, grp) <- tapply(v, grp, fill_down)
## v
## done by built-in function `ave()`
ave(v, grp, FUN=fill_down)
}
要处理多列,一个人可能
elts <- c("age", "birthplace")
df[elts] <- lapply(df[elts], fill_down_by_group, df$name)
笔记
library(dplyr); library(tidyr)
df %>% group_by(name) %>% fill_(elts)
identical(grp, sort(grp))
)时,更有效的基本解决方案是fill_down_by_grouped <- function(v, grp) {
if (length(v) > 1) {
keep <- !(duplicated(v) & is.na(v))
v[keep][cumsum(keep)]
} else v
}
fill_down()
在一个包含大约 10M 元素的向量上需要大约 225 毫秒; fill_down_by_grouped()
需要约 300 毫秒,与组数无关; fill_down_by_group()
与组数成比例; 10000组~2s,10M组约36s 关于r - 如何按组用最新的非 NA 替换 NA?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39063253/