2017-03-14 54 views
2

我必須處理大量的數據集,這就是爲什麼我必須使用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 

問題 - 是否可以在這樣的任務中使用字符串?

+3

嘗試'dt [n,on =「a」]'或'dt [eval(as.name(「a」))%in%n]'或'setkeyv (dt,「a」)[n]' –

+0

@David也可以做出答案。我認爲'eval'應該在整個'i'上,而不僅僅是名稱,以便使用autoindexing。 – Frank

+0

@Frank我們有沒有對這個地方有一些欺騙?也許[這](http://stackoverflow.com/questions/27677283/evaluating-both-column-name-and-the-target-value-within-j-expression-within-d)? –

回答

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] 

您可能需要考慮的幾點。

in 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]),如果只運行一次,速度會更快。在某些情況下,臨時索引將在每次運行中創建(例如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]提出)

+0

使用'setindex()'而不是'setkey()'明確設置一個二級索引是什麼?比較'DT < - data.table(a = 1:2); DT [。(1L),on =。(a),verbose = TRUE]; DT [。(1L),on =。(a),verbose = TRUE]的DT [。(1L),on =。(a),verbose = TRUE]'。 setindex(DT,a); DT [。(1L),on =。(a),verbose = TRUE]'。 – Uwe

0

使用get功能

dt[get('a') %in% n] 

如果colname的存儲在另一個變量,它也可以工作:

temp <- 'a' 
dt[get(temp) %in% n] 
+0

'get'在龐大的數據集上很慢。 –

相關問題