相关疑难解决方法(0)

以编程方式将列名称传递给data.table

我希望能够编写一个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)

r data.table

11
推荐指数
1
解决办法
2807
查看次数

r - 将变量作为data.table列名传递

我使用它越多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应该这样做的路线?

r data.table

7
推荐指数
1
解决办法
1253
查看次数

r data.table函数式编程/元编程/计算语言

我正在探索使用data.table包装聚合函数(但实际上它可以是任何类型的函数)的不同方法(也提供了一个dplyr示例)并且想知道关于函数式编程/元编程的最佳实践

  • 性能(实现是否与data.table可能适用的潜在优化有关)
  • 可读性(有一个共同商定的标准,例如在大多数使用data.table的包中)
  • 易于推广(元编程是否具有"推广性"的方式存在差异)

基本应用是灵活地聚合表,即参数化变量以聚合,聚合的维度,两者的相应结果变量名称和聚合函数.我已经在三个data.table和一个dplyr方式中实现了(几乎)相同的功能:

  1. fn_dt_agg1(这里我无法弄清楚如何参数化聚合函数)
  2. fn_dt_agg2(由@jangorecki的回答启发这里,他称之为'上的语言计算’)
  3. fn_dt_agg3(灵感来自@Arun的答案,这似乎是元编程的另一种方法)
  4. fn_df_agg1(我在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)

functional-programming r metaprogramming dplyr data.table

6
推荐指数
1
解决办法
704
查看次数

如何在函数和循环中使用data.table?

在评估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)

注意(感谢下面的回复):如果您需要通过引用更改变量值,则需要使用 …

loops r function dplyr data.table

4
推荐指数
2
解决办法
2433
查看次数

具有多个条件的内部联接r数据表

我正在尝试使用具有多个相当动态条件的数据表进行内部联接。我被语法绊倒了。首先,我创建两个对象,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)

r inner-join cross-join data.table

3
推荐指数
1
解决办法
125
查看次数

按变量定义的条件过滤行

我有以下几点 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.

r subset data.table

1
推荐指数
1
解决办法
40
查看次数