首页 > 解决方案 > 如何将特定于列的参数传递给 data.table .SD 中的 lapply?

问题描述

.SD我已经看到了使用with lapplyindata.table和一个简单函数的例子,如下所示:

DT[ , .(b,d,e) := lapply(.SD, tan), .SDcols = .(b,d,e)]

但我不确定如何在多参数函数中使用特定于列的参数。例如,我有一个winsorize函数,我想将它应用于数据表中的列子集,但使用特定于列的百分位数,例如

library(DescTools)
wlevel <- list(b=list(lower=0.01,upper=0.99), c=list(upper=0.02,upper=0.95))
DT[ , .(b,c) :=lapply(.SD, function(x) 
{winsorize(x,wlevel$zzz$lower,wlevel$zzz$upper)}), .SDcols = .(b,c)]

zzz要迭代的相应列在哪里。我还看到了有关使用更改参数的线程,lapply但不是在数据表的上下文中.SDcols

这可能吗?

这是一个玩具示例,旨在推广任意大量列的情况;循环始终是一种选择,但试图看看是否有更优雅/有效的解决方案......

标签: rdata.tableparameter-passinglapplymapply

解决方案


如何在多参数函数中使用特定于列的参数?

使用mapply(FUN, dat, params1, params2, ...)where eachparams1, params2, ...可以是列表或向量;mapply并行迭代每个dat, params1, params2, ...

请注意,与该apply/lapply/sapply系列的其他部分不同,mapply函数参数首先出现,然后是数据和参数。

在您的情况下(伪代码,您需要对其进行调整以使其运行),例如:

而不是你的嵌套列表wlevel <- list(b=list(lower=0.01,upper=0.99), c=list(upper=0.02,upper=0.95)),可能更容易解压到:

w_lower <- list(b=0.01, c=0.02)
w_upper <- list(b=0.99, c=0.95) 

DT[ , c('b','c') := mapply(function(x, w_lower_col, w_upper_col) { winsorize(x, w_lower_col, w_upper_col) },
  .SD, w_lower, w_upper), .SDcols = c('b', 'c')]

我们不应该zzz在索引到列表时使用列名(您的),而mapply()应该按原样迭代列表。


推荐阅读