gpt4 book ai didi

r - 使用类别增长率填充 data.table 中的缺失值

转载 作者:行者123 更新时间:2023-12-02 02:47:56 25 4
gpt4 key购买 nike

我有不完整的(时间)系列,我想使用其他系列(国家/地区)的可用近期值和增长率来填补缺失值。类别、缺失值不等长。这需要按顺序对变量应用一个函数:首先我需要获取最后一个可用数据点(可以是任何地方)并将其除以 1+ 增长率,然后移动到下一个数据点并执行相同的操作。

示例数据集和期望的结果:

require(data.table)
DT_desired<-data.table(category=c(rep("A",4),rep("B",4)),
year=2010:2013,
grwth=c(NA,.05,0.1,0,NA,0.1,0.15,0.2))
DT_desired[,values:=c(cumprod(c(1,DT_desired[category=="A"&!is.na(grwth),grwth]+1)),cumprod(c(1,DT_desired[category=="B"&!is.na(grwth),grwth]+1)))]

DT_example <- copy(DT_desired)[c(1,2,3,5),values:=NA]

我尝试了什么:您可以通过 for 循环来完成,但在 R 中这样做效率低下且不受欢迎。我开始喜欢 data.table 的效率,我更愿意以这种方式进行。我试过数据表的移位功能,它只填充一个缺失值(这是合乎逻辑的,因为它试图同时执行我猜,当其余的缺失前一个值时)。

DT_example[,values:=ifelse(is.na(values),shift(values,type = "lead")/(1+shift(grwth,type = "lead")),values),by=category]

我从其他帖子了解到,您可能可以使用 zoo 包的 rollapply 函数来完成它,但我只是觉得我应该能够在数据表中完成它而无需另一个额外的包,并且解决方案比较简洁大方,只是我经验不够,找不到。

这很可能是重复的,很抱歉,如果我没有注意到合适的帖子,但我发现的都不是我想要的。

最佳答案

不确定这是否已在 SO 之外解决,但前几天引起了我的注意。我已经很长时间没有编写 Rcpp 了,我认为这是一个很好的实践。我知道您正在寻找原生的 data.table 解决方案,所以请随意选择或保留它:

foo.cpp 文件的内容:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
NumericVector fillValues(NumericVector vals, NumericVector gRates){

int n = vals.size();
NumericVector out(n);

double currentValue = vals[n - 1];
double currentGrowth = gRates[n - 1];

// initial assignment
out[n - 1] = currentValue;

for(int i = n - 2; i >= 0; i--){

if(NumericVector::is_na(vals[i])){
// If val[i] is na, we need prior values to populate it
if(!((currentValue || currentValue == 0) && (currentGrowth || currentGrowth == 0))){
// We need a currentValue and currentGrowth to base growth rate on, throw error
Rcpp::stop("NaN Values for rates or value when needed actual value");
} else {
// Update value
out[i] = currentValue / (1 + currentGrowth);
}
} else {
out[i] = vals[i];
}

// update
currentValue = out[i];
if(!NumericVector::is_na(gRates[i])){
currentGrowth = gRates[i];
}
}

return out;
}

/*** R
require(data.table)
DT_desired<-data.table(category=c(rep("A",4),rep("B",4)),
year=2010:2013,
grwth=c(NA,.05,0.1,0,NA,0.1,0.15,0.2))

DT_desired[,values:=c(cumprod(c(1,DT_desired[category=="A"&!is.na(grwth),grwth]+1)),cumprod(c(1,DT_desired[category=="B"&!is.na(grwth),grwth]+1)))]

DT_example <- copy(DT_desired)[c(1,2,3,5),values:=NA]

DT_desired[]
DT_example[]

DT_example[, values:= fillValues(values, grwth)][]
*/

然后运行它:

> Rcpp::sourceCpp('foo.cpp')

# Removed output that created example data

> DT_desired[]
category year grwth values
1: A 2010 NA 1.000
2: A 2011 0.05 1.050
3: A 2012 0.10 1.155
4: A 2013 0.00 1.155
5: B 2010 NA 1.000
6: B 2011 0.10 1.100
7: B 2012 0.15 1.265
8: B 2013 0.20 1.518

> DT_example[]
category year grwth values
1: A 2010 NA NA
2: A 2011 0.05 NA
3: A 2012 0.10 NA
4: A 2013 0.00 1.155
5: B 2010 NA NA
6: B 2011 0.10 1.100
7: B 2012 0.15 1.265
8: B 2013 0.20 1.518

> DT_example[, values:= fillValues(values, grwth)][]
category year grwth values
1: A 2010 NA 1.000
2: A 2011 0.05 1.050
3: A 2012 0.10 1.155
4: A 2013 0.00 1.155
5: B 2010 NA 1.000
6: B 2011 0.10 1.100
7: B 2012 0.15 1.265
8: B 2013 0.20 1.518

请注意,这是从后往前运行的,因此它假设您要从最近的记录开始,然后从更远的地方开始记录。它还假定您的数据集已排序。

关于r - 使用类别增长率填充 data.table 中的缺失值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53502568/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com