r - 如何按组用最新的非 NA 替换 NA?

标签 r

这个问题在这里已经有了答案:





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)

笔记
  • 我有兴趣了解 dplyr 解决方案如何处理多列,而不对每一列进行硬编码?回答我自己的问题,我想这是
    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/

    相关文章:

    r - 对于数据帧行的直方图,“x”必须是数字

    使用 tidyr::nest() 时保留 dplyr::group_by 列

    将匹配的字符串替换为其子组

    r - 将查询包含在 R 包中

    r - 如何从ggtheme中删除框架

    python - pandas 和 rpy2 : Why does ezANOVA work via robjects. r 但不是 robjects.packages.importr?

    r - 在 R 的 data.table 中添加一个空列表作为值

    r - 使用 Shiny 仪表板 [R] 设置框的最小/最大宽度

    r - 如果第 1 列值低于第 2 列和第 3 列值,如何删除行?

    r - Extrafont和ggsave:字符最终在另一个字符之上