Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R data.table按列名称列出的操作_R_Data.table - Fatal编程技术网

R data.table按列名称列出的操作

R data.table按列名称列出的操作,r,data.table,R,Data.table,假设我有一个data.table a <- data.table(id=c(1,1,2,2,3),a=21:25,b=11:15,key="id") 但是,假设我有列名: (c中的n(“a”、“b”)){ s编辑2020-02-15关于。 data.table还支持。语法“查找级别”,在大多数情况下,例如下面的dt[,…n1]和dt[,…n2]都不需要with=FALSE 查看数据中的和。表: dt <- data.table(id=1:5,a=21:25,b=11:15,key

假设我有一个
data.table

a <- data.table(id=c(1,1,2,2,3),a=21:25,b=11:15,key="id")
但是,假设我有列名:

(c中的n(“a”、“b”)){ s编辑2020-02-15关于
data.table
还支持
语法“查找级别”,在大多数情况下,例如下面的
dt[,…n1]
dt[,…n2]
都不需要
with=FALSE


查看
数据中的
。表

dt <- data.table(id=1:5,a=21:25,b=11:15,key="id")
dt[, n3 := dt[ , n1, with = FALSE ] * dt[ , n2, with = FALSE ], with = FALSE ]
dt这类似于:

但是您也希望将它与
by=
相结合,因此
set()
不够灵活。这是一种经过深思熟虑的设计,在这方面
set()
不太可能改变

我有时会在回答的末尾使用
EVAL
助手。

有些人对这种方法感到畏缩,但我只是认为它就像构造一个动态SQL语句,这是一种非常常见的做法。
EVAL
方法提供了极大的灵活性,而不必对
EVAL()
quote()
。查看已构造的动态查询(检查它)您可以在
EVAL
helper函数中添加
print

但是,在这个简单的示例中,您可以用括号将
:=
的LHS括起来,告诉
数据。table
查找值(比
with=FALSE
更清晰),RHS需要一个
get()

(c中的n(“a”、“b”)){ s您也可以这样做:

a <- data.table(id=c(1,1,2,2,3),a=21:25,b=11:15,key="id")

a[, c("sa", "sb") := lapply(.SD, sum), by = id]

下面是一种方法,它使用
.SD

# a helper function
makeCall <- function(x,fun) bquote(.(fun)(.(x)))
# the columns you wish to sum (apply function to)
cols <- c('a','b')
new.cols <- paste0('s',cols)
# create named list of names
name.cols <- setNames(sapply(cols,as.name), new.cols)
# create the call
my_call <-  as.call(c(as.name(':='), lapply(name.cols, makeCall, fun = as.name('sum'))))
(a[, eval(my_call), by = 'id'])

#    id  a  b sa sb
# 1:  1 21 11 43 23
# 2:  1 22 12 43 23
# 3:  2 23 13 47 27
# 4:  2 24 14 47 27
# 5:  3 25 15 25 15
#辅助函数

makeCall可能相关:而且有点老:…和data.table FAQ中的1.6。@joran:我不知道如何在这里使用
eval
/
quote
;我尝试了
s@sds,我只是在头脑风暴。不过,我很同情。data.table为我造成的这类问题的混乱程度是我不使用它的最大原因经常。我不需要
s
周围的参数,是吗?是的,否则它将在循环的两次迭代中创建一个名为
“s”
的列。哦,对不起-我错过了
with=FALSE
。我们已经向
(LHS)移动了:=
因为这更容易阅读。
with=FALSE
不清楚它指的是
的LHS还是RHS:=
。这提醒了我,当使用
:=
时,我们应该正式地反对
with=FALSE
。对,所以问题不大。只要用
get(n)包装
n
是所需的全部。错误来自
sum(“a”)
+1甚至更好,因为它是在一个单独的分组中进行的,而不是一个一个地添加每个列的分组。在这种情况下使用
.SD
不应该起作用,因为
.SD
中的所有数据都被使用。@MattDowle作为旁白-使用
.SD
的主要作用发生在
[.data.table
由于该函数的巨大开销而被涉及,因此类似于
.SD[1:N]
的东西在
.SD
的“by”循环中会慢几个数量级。哦,是的,谢谢提醒。它在列表中可以优化。@eddi,只是提醒讨论。它不仅仅是
[.data.table
。它肯定会让事情变慢。但仅仅评估
.SD
似乎也会让事情变慢。我将用data.frame和data.table以及post back做一个适当的基准测试。
dt <- data.table(id=1:5,a=21:25,b=11:15,key="id")
dt[ , dt.names["n3"] := 1L, with = FALSE ]

dt.names <- c( n1 = "a", n2 = "b", n3 = "c" )
setnames( dt, dt.names, names(dt.names) )

dt[ , n3 := n1 * n2, by = "id" ]
setnames( dt, names(dt.names), dt.names )
for (n in c("a","b")) {
  s <- paste0("s",n)
  a[, (s) := sum(get(n)), by="id"]
}
a <- data.table(id=c(1,1,2,2,3),a=21:25,b=11:15,key="id")

a[, c("sa", "sb") := lapply(.SD, sum), by = id]
cols.to.sum = c("a", "b")
a[, paste0("s", cols.to.sum) := lapply(.SD, sum), by = id, .SDcols = cols.to.sum]
# a helper function
makeCall <- function(x,fun) bquote(.(fun)(.(x)))
# the columns you wish to sum (apply function to)
cols <- c('a','b')
new.cols <- paste0('s',cols)
# create named list of names
name.cols <- setNames(sapply(cols,as.name), new.cols)
# create the call
my_call <-  as.call(c(as.name(':='), lapply(name.cols, makeCall, fun = as.name('sum'))))
(a[, eval(my_call), by = 'id'])

#    id  a  b sa sb
# 1:  1 21 11 43 23
# 2:  1 22 12 43 23
# 3:  2 23 13 47 27
# 4:  2 24 14 47 27
# 5:  3 25 15 25 15