相关疑难解决方法(0)

Data.table元编程

我认为元编程在这里是正确的术语.

我希望能够使用data.table,就像在webapp中使用MySQL一样.也就是说,Web用户使用一些Web前端(例如Shiny服务器)来选择数据库,选择要过滤的列,选择要分组的列,选择要聚合的列和聚合函数.我想使用R和data.table作为查询,聚合等的后端.假设前端存在,R将这些变量作为字符串,并验证它们等.

我编写了以下函数来构建data.table表达式并使用R的parse/eval元编程功能来运行它.这是一种合理的方法吗?

我包括所有相关代码来测试这个.获取此代码(在读取安全性之后!)并运行test_agg_meta()来测试它.这只是一个开始.我可以添加更多功能.

但我的主要问题是我是否过度思考这一点.有没有更直接的方法来使用data.table,所有的输入都是事先确定的,而不需要求助于parse/eval元编程?

我也知道"with"声明和一些其他无糖功能方法,但不知道他们是否可以处理所有情况.

require(data.table)

fake_data<-function(num=12){
  #make some fake data
  x=1:num
  lets=letters[1:num]
  data=data.table(
    u=rep(c("A","B","C"),floor(num/3)),
    v=x %%2, w=lets, x=x, y=x^2, z=1-x)
  return(data)
}

data_table_meta<-function(
  #aggregate a data.table meta-programmatically
  data_in=fake_data(),
  filter_cols=NULL,
  filter_min=NULL,
  filter_max=NULL,
  groupby_cols=NULL,
  agg_cols=setdiff(names(data_in),groupby_cols),
  agg_funcs=NULL,
  verbose=F,
  validate=T,
  jsep="_"
){

  all_cols=names(data_in)

  if (validate) {
    stopifnot(length(filter_cols) == length(filter_min))
    stopifnot(length(filter_cols) == length(filter_max))
    stopifnot(filter_cols %in% all_cols)
    stopifnot(groupby_cols %in% all_cols)
    stopifnot(length(intersect(agg_cols,groupby_cols)) == 0)
    stopifnot((length(agg_cols) == length(agg_funcs))  | (length(agg_funcs)==1) | (length(agg_funcs)==0))
  }

  #build the command

  #defaults
  i_filter=""
  j_select=""
  n_agg_funcs=length(agg_funcs)
  n_agg_cols=length(agg_cols)
  n_groupby_cols=length(groupby_cols)
  if (n_agg_funcs == 0) …
Run Code Online (Sandbox Code Playgroud)

r data.table

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

eval和data.table中的引用

我在这里错过了什么?

d = data.table(a = 1:5)

d[, a]                   # 1 2 3 4 5
d[, sum(a)]              # 15

d[, eval(quote(a))]      # 1 2 3 4 5
d[, sum(eval(quote(a)))] # 15

quoted_a = quote(a)
d[, eval(quoted_a)]      # 1 2 3 4 5
d[, sum(eval(quoted_a))] # Error in eval(expr, envir, enclos) : object 'a' not found
Run Code Online (Sandbox Code Playgroud)

到底是怎么回事?我跑R 2.15.0data.table 1.8.9.

r data.table

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

R在data.table(或ddply)中动态构建"list"

我的聚合需求因列/ data.frames而异.我想动态地将"list"参数传递给data.table.

作为一个最小的例子:

require(data.table)
type <- c(rep("hello", 3), rep("bye", 3), rep("ok",3))
a <- (rep(1:3, 3))
b <- runif(9)
c <- runif(9)
df <- data.frame(cbind(type, a, b, c), stringsAsFactors=F)
DT <-data.table(df)
Run Code Online (Sandbox Code Playgroud)

这个电话:

DT[, list(suma = sum(as.numeric(a)), meanb = mean(as.numeric(b)), minc = min(as.numeric(c))), by= type]
Run Code Online (Sandbox Code Playgroud)

会有类似的结果:

    type suma     meanb      minc
1: hello    6 0.1332210 0.4265579
2:   bye    6 0.5680839 0.2993667
3:    ok    6 0.5694532 0.2069026
Run Code Online (Sandbox Code Playgroud)

未来的data.frames将有更多的列,我想要以不同的方式进行总结.但是为了使用这个小例子:有没有办法以编程方式传递列表?

我天真地尝试过:

# create a different list
mylist <- "list(lengtha = length(as.numeric(a)), maxb = max(as.numeric(b)), meanc = …
Run Code Online (Sandbox Code Playgroud)

r aggregation plyr data.table

12
推荐指数
4
解决办法
1876
查看次数

按变量定义的条件过滤行

我有以下几点 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
查看次数

标签 统计

data.table ×4

r ×4

aggregation ×1

plyr ×1

subset ×1