按组高效填充NAS [英] Efficiently fill NAs by group

查看:3
本文介绍了按组高效填充NAS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个数据集,其中我观察到一些人的变量,而不是另一些人的变量。对于那些我观察到变量的个体,我只观察一次。然而,每个人的观测次数以及观测值的位置各不相同。

我想用非NA值填充给定个体的所有NA值,以防存在非NA值。否则,NAS应保持为NA。

以下是一个数据集示例:

#data.frame of 100 individuals with 10 observations each
data <- data.frame(group = rep(1:100,each=10),value = NA)

#first 50 individuals get a value at the fifth observation, others don't have value
data$value[seq(5,500,10)] <- rnorm(50)

到目前为止还不错,不是什么大问题。取自另一个线程,我们可以使用dplyrtidyr做类似的事情:

data <- data %>% 
  group_by(group) %>% #by group
  fill(value) %>% #default direction down
  fill(value, .direction = "up") #also fill NAs upwards

这很好地解决了问题。然而,我必须在大约8000万美元的时间里这样做。观察,这需要几个小时。有没有更快的方法?我认为data.table可能是一个很好的候选人。

如果可以将该方法调整为仅填充值之前出现的Nas,那也是很好的。

谢谢!

推荐答案

这是我使用的代码:您的代码和我的代码。有时,动物园不是最快的过程,但它是最干净的。无论如何,您可以测试它。

更新: 到目前为止,它已经用更多的数据(100.000)进行了测试,并且Process 03(子集和合并)获胜。

上次更新 与rBenchmark的功能比较:

library(dplyr)
library(tidyr)
library(base)
library(data.table)
library(zoo)
library(rbenchmark)

#data.frame of 100 individuals with 10 observations each
data <- data.frame(group = rep(1:10000,each=10),value = NA)
data$value[seq(5,5000,10)] <- rnorm(50) #first 50 individuals get a value at the fifth observation, others don't have value

#Process01
P01 <- function (data){
    data01 <- data %>% 
        group_by(group) %>% #by group
            fill(value) %>% #default direction down
            fill(value, .direction = "up") #also fill NAs upwards
    return(data01)
}

#Process02
P02 <- function (data){
    data02 <- setDT(data)[, value := na.locf(na.locf(value, na.rm = FALSE), 
                                             fromLast = TRUE), group]
    return(data02)
}

#Process03
P03 <- function (data){
    dataU <- subset(unique(data), value!='NA') #keep row number
    dataM <- merge(data, dataU, by = "group", all=T) #merge tables
    data03 <- data.frame(group=dataM$group, value = dataM$value.y) #idem shape of data
    return(data03)
}

benchmark("P01_dplyr" = {data01 <- P01(data)},
          "P02_zoo" = {data02 <- P02(data)},
          "P03_data.table" = {data03 <- P03(data)},
          replications = 10,
          columns = c("test", "replications", "elapsed")
          )

数据=10.000、10代表和i57400的结果:

    test replications elapsed
1      P01_dplyr           10  257.78
2        P02_zoo           10   10.35
3 P03_data.table           10    0.09

这篇关于按组高效填充NAS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆