当前位置: 首页 > 知识库问答 >
问题:

选择/分配数据。当变量名存储在字符向量中时的表

连翰
2023-03-14

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

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

如何对数据执行相同的操作。表,带或不带:=符号?dt[,list(colname)]显然不起作用(我也没想到它会起作用)。

共有3个答案

邢皓
2023-03-14
library(data.table)

x <- data.table(this=1:2,that=1:2,whatever=1:2)

# === explicit call
x[, .(that, whatever)]
x[, c('that', 'whatever')]

# === indirect via  variable
# ... direct assignment
mycols <- c('that','whatever')
# ... same as result of a function call
mycols <- grep('a', colnames(x), value=TRUE)

x[, ..mycols]
x[, .SD, .SDcols=mycols]

# === direct 1-liner usage
x[, .SD, .SDcols=c('that','whatever')]
x[, .SD, .SDcols=grep('a', colnames(x), value=TRUE)]

这一切都产生了

   that whatever
1:    1        1
2:    2        2

我找到了。SDcols方式最优雅。

南宫海超
2023-03-14

*这不是一个真正的答案,但我没有足够的街头信誉来发表评论:/

无论如何,对于那些可能希望在数据表中使用存储在变量中的名称实际创建新列的人,我有以下工作要做。我对它的性能一无所知。有什么改进的建议吗?假设一个无名的新列总是被命名为V1安全吗?

colname <- as.name("users")
# Google Analytics query is run with chosen metric and resulting data is assigned to DT
DT2 <- DT[, sum(eval(colname, .SD)), by = country]
setnames(DT2, "V1", as.character(colname))

注意,我可以在sum()中引用它,但似乎无法在同一步骤中分配它。顺便说一句,我需要这样做的原因是colname将基于闪亮应用程序中的用户输入。

竺鸿骞
2023-03-14

以编程方式选择变量的两种方法:

>

 DT = data.table(col1 = 1:3)
 colname = "col1"
 DT[, colname, with = FALSE] 
 #    col1
 # 1:    1
 # 2:    2
 # 3:    3

“点-点”()前缀:

 DT[, ..colname]    
 #    col1
 # 1:    1
 # 2:    2
 # 3:    3

有关“点-点”()符号的进一步说明,请参阅1.10中的新功能。2(帮助文本中目前未对其进行描述)。

要分配给变量,请将:=的左括号括起来:

DT[, (colname) := 4:6]    
#    col1
# 1:    4
# 2:    5
# 3:    6

后者被称为列plonk,因为通过引用替换整个列向量。如果存在一个子集i,它将通过引用进行子分配。(colname)是v1版中引入的缩写。2014年10月9日至4日。新闻如下:

使用with=FALSEwith:=现在在所有情况下都不建议使用,因为用括号包装:=的LHS已经有一段时间了。

colVar = "col1"
DT[, (colVar) := 1]                             # please change to this
DT[, c("col1", "col2") := 1]                    # no change
DT[, 2:4 := 1]                                  # no change
DT[, c("col1","col2") := list(sum(a), mean(b))]  # no change
DT[, `:=`(...), by = ...]                       # no change

另请参见中的详细信息部分?':='

DT[i, (colnamevector) := value]
# [...] The parens are enough to stop the LHS being a symbol

为了回答评论中的进一步问题,这里有一种方法(通常有很多方法):

DT[, colname := cumsum(get(colname)), with = FALSE]
#    col1
# 1:    4
# 2:    9
# 3:   15 

或者,您可能会发现只需对evalapaste进行读、写和调试就更容易了,这类似于构造要发送到服务器的动态SQL语句:

expr = paste0("DT[,",colname,":=cumsum(",colname,")]")
expr
# [1] "DT[,col1:=cumsum(col1)]"

eval(parse(text=expr))
#    col1
# 1:    4
# 2:   13
# 3:   28

如果经常这样做,可以定义一个helper函数EVAL

EVAL = function(...)eval(parse(text=paste0(...)),envir=parent.frame(2))

EVAL("DT[,",colname,":=cumsum(",colname,")]")
#    col1
# 1:    4
# 2:   17
# 3:   45

既然data.table1.8.2自动优化了j以提高效率,那么最好使用ava方法。例如,j中的get()阻止了一些优化。

或者,有set()。一个低开销、函数形式的:=,在这里很好。参见?设置

set(DT, j = colname, value = cumsum(DT[[colname]]))
DT
#    col1
# 1:    4
# 2:   21
# 3:   66
 类似资料:
  • 我有这种情况: 其中变量名和相对数据存储在字符串中,如上例所示。特别是,每个variable_name/its_data单元由分隔。在是相对数据。 我想要一个这样的最终数据帧:

  • 问题内容: 我是JAVA的初学者,我正在编写这段代码,该代码应该接收字符串数组并将每个字符串(数组元素)分别存储在指定的变量中。但是它仅存储第一个元素。下面是代码: 问题答案:

  • 因此,为了测试我的搜索结果是否因我输入的关键字而异,我想在键入关键字之前存储搜索结果的节点列表,然后将它们与添加关键字后得到的搜索结果的节点列表进行比较,但我无法使其起作用。 我试过: 然而,这并没有给我一个节点。我还试图使用一个带有的clientFunction,但是TestCafe然后告诉我使用Selector。 要怎么做?有没有更好的方法来测试这个,我没看到?

  • 问题内容: 因此,我正在编写此存储过程,而且我真的很喜欢SQL。 我对你们的问题是: 我可以选择整行并将其存储在变量中吗? 我知道我可以做类似的事情: 但是我可以从中选择整行并将其存储在变量中吗? 问题答案: 您可以将字段选择为多个变量: 另一种可能更好的方法是使用表变量: 然后,您可以像常规表一样从表变量中进行选择。

  • 问题内容: 我有一个表,用于存储目录信息(例如在文件系统中)。每个目录(命名节点)都有一个和一个。我想尽可能有效地检索完整路径。为此,我试图使以下查询正常工作,但是这些查询仅返回预期的第一行(实际上是最里面的目录)。任何人都可以帮助获取完整的结果集,以便也选择给定目录/节点的所有层次结构父级。 我目前正在尝试的查询: 选择: 选择: 样本数据: 所需的输出: 谁能帮忙吗? 问题答案: 您已经错过了

  • 选择恰当的分片数量和分片副本数量 最开始使用ElasticSearch时,一般都是创建一个索引,导入数据,然后发送查询命令检索数据。我们确信系统运行庚子,至少在最开始,数据量不大而且QPS(Query Per Second)也不高的时候运行良好。在幕后,ElasticSearch创建了一些分片来存储数据,也可能还会创建分片副本(例如,如果用默认配置),而且用户在配置方面也不用过多地操心。 当应用程