相关疑难解决方法(0)

使用以下内容分配多个列:= data.table,group

使用分配给多个列的最佳方法是什么data.table?例如:

f <- function(x) {c("hi", "hello")}
x <- data.table(id = 1:10)
Run Code Online (Sandbox Code Playgroud)

我想做这样的事情(当然这种语法不正确):

x[ , (col1, col2) := f(), by = "id"]
Run Code Online (Sandbox Code Playgroud)

为了扩展它,我可能有很多列的名称存储在一个变量(比如说col_names)中,我想这样做:

x[ , col_names := another_f(), by = "id", with = FALSE]
Run Code Online (Sandbox Code Playgroud)

做这样的事的正确方法是什么?

r variable-assignment dataframe data.table colon-equals

115
推荐指数
2
解决办法
7万
查看次数

使用变量在data.table中传递列名

可能重复:
可变地选择/分配data.table中的字段

在下面的示例中,我创建了一个列名为"x"和"v"的数据表

library('data.table')
DT <- data.table(x = c("b","b","b","a","a"), v = rnorm(5))
Run Code Online (Sandbox Code Playgroud)

我可以通过以下方式访问列'x'的值:

DT[ , x]
# [1] "b" "b" "b" "a" "a"
Run Code Online (Sandbox Code Playgroud)

但是如果我想通过传递变量来访问它,它就不起作用

temp <- "x"
DT[ , temp]
# [1] "x"
Run Code Online (Sandbox Code Playgroud)

将有多个列,我将只为其中几个选择值.我将通过R模块提供这些列名.

没关系,我明白了,它应该是:

DT[ , get(temp)]
Run Code Online (Sandbox Code Playgroud)

r data.table

85
推荐指数
1
解决办法
8万
查看次数

当变量名存储在字符向量中时,选择/分配给data.table

data.table如果变量名存储在字符向量中,如何引用变量?例如,这适用于data.frame:

df <- data.frame(col1 = 1:3)
colname <- "col1"
df[colname] <- 4:6
df
#   col1
# 1    4
# 2    5
# 3    6
Run Code Online (Sandbox Code Playgroud)

如何使用或不使用:=表示法对data.table执行相同的操作?显而易见的事情是dt[ , list(colname)]行不通的(我也没想到).

r data.table

78
推荐指数
3
解决办法
2万
查看次数

R使用data.table汇总多个列

我正在尝试使用data.table来加速处理由几个较小的合并data.frames组成的大型data.frame(300k x 60).我是data.table的新手.到目前为止的代码如下

library(data.table)
a = data.table(index=1:5,a=rnorm(5,10),b=rnorm(5,10),z=rnorm(5,10))
b = data.table(index=6:10,a=rnorm(5,10),b=rnorm(5,10),c=rnorm(5,10),d=rnorm(5,10))
dt = merge(a,b,by=intersect(names(a),names(b)),all=T)
dt$category = sample(letters[1:3],10,replace=T)
Run Code Online (Sandbox Code Playgroud)

我想知道是否有比以下更有效的方法来总结数据.

summ = dt[i=T,j=list(a=sum(a,na.rm=T),b=sum(b,na.rm=T),c=sum(c,na.rm=T),
                     d=sum(d,na.rm=T),z=sum(z,na.rm=T)),by=category]
Run Code Online (Sandbox Code Playgroud)

我真的不想手工输入所有50列计算,而且eval(paste(...))似乎很笨拙.

我看了下面的例子,但对我的需求似乎有点复杂.谢谢

如何跨多个列汇总data.table

r data.table

52
推荐指数
1
解决办法
5万
查看次数

通过保存在变量中的名称引用data.table列

data.table是一个梦幻般的R包,我在我正在开发的库中使用它.到目前为止,一切都很顺利,除了一个并发症.data.table使用保存在变量中的名称来引用列(例如:对于数据帧),似乎要比使用常规数据帧更难(与传统数据帧相比colname="col"; df[df[,colname]<5,colname]=0).

也许最让事情变得复杂的是这种语法明显缺乏一致性data.table.在某些情况下,eval(colname)get(colname),甚至c(colname)似乎工作.在其他方面,DT[,colname, with=F]是解决方案.然而在其他方面,例如,set()subset()功能,我根本没有找到解决方案.最后,前面讨论了一个极端的,虽然也是非常常见的用例(以编程方式将列名称传递给data.table),并且建议的解决方案虽然显然正在完成他们的工作,但似乎并不特别可读......

也许我太复杂了?如果有人可以记下快速备忘单,以便data.table使用不同常见场景的变量来引用列名,我将非常感激.

更新:

提供的一些具体示例我可以硬编码列名:

x.short = subset(x, abs(dist)<=100)
set(x, which(x$val<10), "val", 0) 
Run Code Online (Sandbox Code Playgroud)

现在假设distcol="dist",valcol="val".使用distcoland valcol,但不是distval?的最佳方法是什么?

r data.table

41
推荐指数
2
解决办法
2万
查看次数

data.table中的动态列名称

我正在尝试向我添加列data.table,其中名称是动态的.另外,我需要by在添加这些列时使用参数.例如:

test_dtb <- data.table(a = sample(1:100, 100), b = sample(1:100, 100), id = rep(1:10,10))
cn <- parse(text = "blah")
test_dtb[ , eval(cn) := mean(a), by = id]

# Error in `[.data.table`(test_dtb, , `:=`(eval(cn), mean(a)), by = id) : 
#  LHS of := must be a single column name when with=TRUE. When with=FALSE the LHS may be a vector of column names or positions.
Run Code Online (Sandbox Code Playgroud)

另一种尝试:

cn <- "blah"
test_dtb[ , cn := mean(a), by = id, with …
Run Code Online (Sandbox Code Playgroud)

r data.table

32
推荐指数
2
解决办法
2万
查看次数

在`data.table`中使用动态列名

我想计算data.table中每个列的平均值,按另一列分组.我的问题类似于关于SO的另外两个问题(一个两个),但我不能将这些问题应用于我的问题.

这是一个例子:

library(data.table)
dtb <- fread(input = "condition,var1,var2,var3
      one,100,1000,10000
      one,101,1001,10001
      one,102,1002,10002
      two,103,1003,10003
      two,104,1004,10004
      two,105,1005,10005
      three,106,1006,10006
      three,107,1007,10007
      three,108,1008,10008
      four,109,1009,10009
      four,110,1010,10010")

dtb
#    condition var1 var2  var3
# 1:       one  100 1000 10000
# 2:       one  101 1001 10001
# 3:       one  102 1002 10002
# 4:       two  103 1003 10003
# 5:       two  104 1004 10004
# 6:       two  105 1005 10005
# 7:     three  106 1006 10006
# 8:     three  107 1007 10007
# 9:     three …
Run Code Online (Sandbox Code Playgroud)

r data.table

32
推荐指数
1
解决办法
2万
查看次数

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
查看次数

如何编写一个调用调用data.table的函数的函数?

该包data.table具有一些特殊的语法,需要使用表达式作为ij参数.

这对于一个接受并将参数传递给数据表的写函数有一些影响,正如常见问题解答第1.16节中所解释的那样.

但我无法弄清楚如何采取这一额外的水平.

这是一个例子.假设我想编写一个包装函数foo(),它对我的​​数据进行特定的汇总,然后是第二个plotfoo()调用foo()并绘制结果的包装器:

library(data.table)


foo <- function(data, by){
  by <- substitute(by)
  data[, .N, by=list(eval(by))]
}

DT <- data.table(mtcars)
foo(DT, gear)
Run Code Online (Sandbox Code Playgroud)

好的,这是有效的,因为我得到了我的表格结果:

   by  N
1:  4 12
2:  3 15
3:  5  5
Run Code Online (Sandbox Code Playgroud)

现在,我在写作的时候尝试的plotfoo()却是一样但是我悲惨地失败了:

plotfoo <- function(data, by){
  by <- substitute(by)
  foo(data, eval(by))
}
plotfoo(DT, gear)
Run Code Online (Sandbox Code Playgroud)

但这次我收到一条错误消息:

Error: evaluation nested too deeply: infinite recursion / options(expressions=)?
Run Code Online (Sandbox Code Playgroud)

好的,所以eval()导致了问题.我们将其删除:

plotfoo <- function(data, by){
  by …
Run Code Online (Sandbox Code Playgroud)

r data.table

18
推荐指数
2
解决办法
1440
查看次数

使用data.table在"group by"操作中设置列名

我是R中data.table包的新用户.我试图给"group by"命令创建的新列命名

> DT = data.table(x=rep(c("a","b"),c(2,3)),y=1:5) 
> DT
x y
1: a 1
2: a 2
3: b 3
4: b 4
5: b 5
> DT[,{z=sum(y);z+3},by=x]
x V1
1: a 6
2: b 15
Run Code Online (Sandbox Code Playgroud)
  1. 我想直接命名V1(默认)列(不必使用colnames),是否可能?
  2. 另外,是否可以在一个命令中执行多个操作组,这将导致类似于:

       x V1 V2
    1: a 6  something
    2: b 15 something
    
    Run Code Online (Sandbox Code Playgroud)

谢谢

r data.table

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