如果想要根据组内的前/后非NA观察填充变量的缺失值,则data.table命令为
setkey(DT,id,date)
DT[, value_filled_in := DT[!is.na(value), list(id, date, value)][DT[, list(id, date)], value, roll = TRUE]]
Run Code Online (Sandbox Code Playgroud)
这很复杂.这是一个耻辱,因为它roll是一个非常快速和强大的选项(特别是与应用zoo::na.locf每个组内的功能相比)
我可以写一个便利函数来填补缺失的值
fill_na <- function(x , by = NULL, roll =TRUE , rollends= if (roll=="nearest") c(TRUE,TRUE)
else if (roll>=0) c(FALSE,TRUE)
else c(TRUE,FALSE)){
id <- seq_along(x)
if (is.null(by)){
DT <- data.table("x" = x, "id" = id, key = "id")
return(DT[!is.na(x)][DT[, list(id)], x, roll = roll, rollends = rollends, allow.cartesian = TRUE])
} else{
DT <- data.table("x" = x, "by" = by, "id" …Run Code Online (Sandbox Code Playgroud) 我有一个大的,宽的data.table(20米行)由一个人ID键入,但有很多列(~150)有很多空值.每列都是我希望为每个人继承的记录状态/属性.每个人可能有10到10,000个观察点,并且该集合中有大约500,000人.来自一个人的值不能"流血"到下一个人,因此我的解决方案必须适当地尊重人员ID列和组.
出于演示目的 - 这是一个非常小的示例输入:
DT = data.table(
id=c(1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3),
aa=c("A", NA, "B", "C", NA, NA, "D", "E", "F", NA, NA, NA),
bb=c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
cc=c(1, NA, NA, NA, NA, 4, NA, 5, 6, NA, 7, NA)
)
Run Code Online (Sandbox Code Playgroud)
它看起来像这样:
id aa bb cc
1: 1 A NA 1
2: 1 NA NA NA
3: 1 B NA NA
4: 1 …Run Code Online (Sandbox Code Playgroud) 我想检查是否有任何预先存在的把戏na.locf(从zoo包装),rle并inverse.rle在RCpp?
我写了一个循环来实现,例如我做了na.locf(x, na.rm=FALSE, fromLast=FALSE)如下的实现:
#include <Rcpp.h>
using namespace Rcpp;
//[[Rcpp::export]]
NumericVector naLocf(NumericVector x) {
int n=x.size();
for (int i=1;i<n;i++) {
if (R_IsNA(x[i]) & !R_IsNA(x[i-1])) {
x[i]=x[i-1];
}
}
return x;
}
Run Code Online (Sandbox Code Playgroud)
我只是想知道,因为这些是非常基本的功能,有人可能已经RCpp以更好的方式实现它们(可能是避免循环)或更快的方式?