我希望能够编写一个data.table按组运行回归的函数,然后很好地组织结果.以下是我想要做的一个示例:
require(data.table)
dtb = data.table(y=1:10, x=10:1, z=sample(1:10), weights=1:10, thedate=1:2)
models = c("y ~ x", "y ~ z")
res = lapply(models, function(f) {dtb[,as.list(coef(lm(f, weights=weights, data=.SD))),by=thedate]})
#do more stuff with res
Run Code Online (Sandbox Code Playgroud)
我想将所有这些包装成一个函数,因为它#doe more stuff可能很长.我面临的问题是如何将各种名称传递给data.table?例如,如何传递列名weights?我怎么通过thedate?我想象一个看起来像这样的原型:
myfun = function(dtb, models, weights, dates)
Run Code Online (Sandbox Code Playgroud)
让我说清楚:将公式传递给我的函数不是问题.如果weights我想使用和描述日期的列名称thedate已知,那么我的函数可能看起来像这样:
myfun = function(dtb, models) {
res = lapply(models, function(f) {dtb[,as.list(coef(lm(f, weights=weights, data=.SD))),by=thedate]})
#do more stuff with res
}
Run Code Online (Sandbox Code Playgroud)
但是,对应于thedate和对应的列名称weights是事先未知的.我想将它们传递给我的函数:
#this will not work …Run Code Online (Sandbox Code Playgroud) 我使用它越多data.table,替换dplyr为我的'goto'包就越多,因为它提供的速度是一大优点.
题
你可以i在data.table(dt[i,j])中传递变量而不创建一个expression?
例
给出data.table:
library(data.table)
dt <- data.table(val1 = c(1,2,3),
val2 = c(3,2,1))
Run Code Online (Sandbox Code Playgroud)
我想评估一下:
dt[(val1 > val2)]
Run Code Online (Sandbox Code Playgroud)
但使用变量来引用列名.例如,
myCol <- c("val1", "val2") ## vector of column names
Run Code Online (Sandbox Code Playgroud)
我已经阅读了很多问题,通过表达式显示了这样做的方法:
## create an expression to evaluate
expr <- parse(text = paste0(myCol[1], " > ", myCol[2]))
## evaluate expression
dt[(eval(expr))]
val1 val2
1: 3 1
Run Code Online (Sandbox Code Playgroud)
但是我想知道是否有一种更"直接"的方法可以做到这一点,我错过了,类似于:
dt[(myCol[1] > myCol[2])]
Run Code Online (Sandbox Code Playgroud)
或者是expression应该这样做的路线?
我正在探索使用data.table包装聚合函数(但实际上它可以是任何类型的函数)的不同方法(也提供了一个dplyr示例)并且想知道关于函数式编程/元编程的最佳实践
基本应用是灵活地聚合表,即参数化变量以聚合,聚合的维度,两者的相应结果变量名称和聚合函数.我已经在三个data.table和一个dplyr方式中实现了(几乎)相同的功能:
图书馆
library(data.table)
library(dplyr)
Run Code Online (Sandbox Code Playgroud)
数据
n_size <- 1*10^6
sample_metrics <- sample(seq(from = 1, to = 100, by = 1), n_size, rep = T)
sample_dimensions <- sample(letters[10:12], n_size, rep = T)
df <-
data.frame(
a = sample_metrics,
b = sample_metrics,
c = sample_dimensions,
d = sample_dimensions,
x = sample_metrics,
y = sample_dimensions,
stringsAsFactors = F)
dt <- as.data.table(df)
Run Code Online (Sandbox Code Playgroud)
实现
1. fn_dt_agg1
fn_dt_agg1 <-
function(dt, metric, metric_name, dimension, dimension_name) { …Run Code Online (Sandbox Code Playgroud) 在评估data.table(vs. dplyr)的效用时,关键因素是在函数和循环中使用它的能力.
为此,我修改了这篇文章中使用的代码片段:data.table vs dplyr:一个做得好,另一个做不好或做得不好?这样,代替硬编码的数据集变量名称("钻石"数据集的"切割"和"价格"变量),它变得与数据集无关 - 切割n-paste准备好在任何函数或循环内使用(当我们事先不知道列名.
这是原始代码:
library(data.table)
dt <- data.table(ggplot2::diamonds)
dt[cut != "Fair", .(mean(price),.N), by = cut]
Run Code Online (Sandbox Code Playgroud)
这是与数据集无关的等价物:
dt <- data.table(diamonds)
nVarGroup <- 2 #"cut"
nVarMeans <- 7 #"price"
strGroupConditions <- levels(dt[[nVarGroup]])[-1] # "Good" "Very Good" "Premium" "Ideal"
strVarGroup <- names(dt)[nVarGroup]
strVarMeans <- names(dt)[nVarMeans]
qAction <- quote(mean(get(strVarMeans))) #! w/o get() it does not work!
qGroup <- quote(get(strVarGroup) %in% strGroupConditions) #! w/o get() it does not work!
dt[eval(qGroup), .(eval(qAction), .N), by = strVarGroup]
Run Code Online (Sandbox Code Playgroud)
注意(感谢下面的回复):如果您需要通过引用更改变量值,则需要使用 …
我正在尝试使用具有多个相当动态条件的数据表进行内部联接。我被语法绊倒了。首先,我创建两个对象,x并且x2要对其进行内部联接。
set.seed(1)
#generate data
x = data.table(CJ(t=1:10, d=1:3,p1s=seq(1,3,by=0.1),p1sLAST=seq(1,3,by=0.1)))
x[d==1,p1sLAST:=3]
x=x[p1s<=p1sLAST]
x2 = data.table(CJ(tprime=1:10, p1sLASTprm=seq(1,3,by=0.1)))
Run Code Online (Sandbox Code Playgroud)
与对象:
> x
t d p1s p1sLAST
1: 1 1 1.0 3.0
2: 1 1 1.0 3.0
3: 1 1 1.0 3.0
4: 1 1 1.0 3.0
5: 1 1 1.0 3.0
---
9026: 10 3 2.8 2.9
9027: 10 3 2.8 3.0
9028: 10 3 2.9 2.9
9029: 10 3 2.9 3.0
9030: 10 3 3.0 3.0
> x2
tprime p1sLASTprm …Run Code Online (Sandbox Code Playgroud) 我有以下几点 data.table
structure(list(val1 = c(1, 2, 1, 3, 4, 5, 3), val2 = c(4, 5, 6, 4, 2, 4, 5)), .Names = c("val1", "val2"), row.names = c(NA, -7L), class = c("data.table", "data.frame"), .internal.selfref = <pointer: 0xedae28>)
Run Code Online (Sandbox Code Playgroud)
我想要做的是根据其他变量定义的标准过滤其中的行.例如,我可能想要所有的行val1 >= 1.这很容易做到
x[val1 > 1,]
Run Code Online (Sandbox Code Playgroud)
但是,我希望能够将列名称(即,val1或者val2)指定为变量,将过滤器值指定为变量.我试过了
cname = 'val1'
cutoff = 1
x[(cname >= cutoff),] # Try 1
x[(cname) >= (cutoff),] # Try 2
x[eval(cname > cutoff),] # Try 3
Run Code Online (Sandbox Code Playgroud)
但它只是给了原版data.table.