我必须处理大量数据集,这就是我必须使用data.table包的原因。我想只选择在给定列中具有适当值的行。
dt <- data.table(a = rep(c("A", "B", "C"), 3),
b = 1:9)
n <- c("A", "C")
我能做什么:
dt[ a %in% n]
a b
1: A 1
2: C 3
3: A 4
4: C 6
5: A 7
6: C 9
如果我之前不知道列的名称并从函数字符串中获取该怎么办?我试过了:
dt[ "a" %in% n]
Empty data.table (0 rows) of 2 cols: a,b
dt[ "a" %in% n, with = F]
Error in `[.data.table`(dt, "a" %in% n, with = F) :
j must be provided when with=FALSE
dt[ as.name("a") %in% n ]
Error in match(x, table, nomatch = 0L) :
'match' requires vector arguments
问题 - 是否可以在这样的任务中使用字符串?
答案 0 :(得分:1)
可以通过各种方式实现这一目标
使用连接(将返回有序结果,而不对dt
进行排序)
dt[.(n), on = "a"]
或(在排序dt
时也将返回有序结果)
setkeyv(dt, "a")[.(n)]
或使用eval
/ as.name
(将返回未排序的结果)
dt[eval(as.name("a")) %in% n]
或使用列表子集(将返回未排序的结果)
dt[dt[["a"]] %in% n]
您可能需要考虑几点。
在v 1.9.4中,data.table包引入了二级索引。这意味着当您进行矢量扫描(==
或%in%
)时,它会创建某种排序或键(与您明确使用setkey
时的情况类似)第一次运行有点慢,但下次在此列中搜索匹配时会显着提高性能。
但是,并非在所有情况下都会(永久)设置辅助密钥。在某些情况下,它始终是一个简单的矢量扫描(例如dt[eval(as.name("a")) %in% n, verbose = TRUE]
或dt[get('a') %in% n]
或dt[dt[["a"]] %in% n, verbose = TRUE]
),如果您只运行一次,它将会更快。在某些情况下,将在每次运行中创建一个ad-hoc索引(例如dt[n, on = "a", verbose = TRUE]
,但如果它已经存在,也将使用索引),这是次优的,而在某些情况下是永久密钥或辅助密钥将被设置(例如setkeyv(dt, "a")[.(n), verbose = TRUE]
或@Frank dt[eval(substitute(col %in% n, list(col=as.name("a")))), verbose = TRUE]
答案 1 :(得分:0)
使用get
功能
dt[get('a') %in% n]
如果colname存储在另一个变量中,它也有效:
temp <- 'a'
dt[get(temp) %in% n]