2016-04-21 92 views
3

我想排序兩列到我的data.table(id和時間在我的情況)的前面。說我有:R:只改變一些列的data.table中的列順序

library(data.table) 
Data <- as.data.table(iris) 

,說我想要的列的順序是:

example <- Data 
setcolorder(example,c("Species","Petal.Length","Sepal.Length", 
         "Sepal.Width","Petal.Length","Petal.Width")) 

但我的實際數據表有更多的變數,所以我想ADRESS此爲:

setcolorder(Data,c("Species","Petal.Length", 
        names(Data)[!c("Species","Petal.Length")])) 
setcolorder(Data, c("Species","Petal.Length", 
        ...all other variables in their original order...)) 

我喜歡的東西發揮各地

但我有一個問題,通過名稱引用對字符向量名稱(Data)進行子集化。另外我敢肯定,我可以用一些整潔的data.table函數來避免這種解決方法,不是嗎?

回答

6

我們可以使用setdiff於子集不在的names即「NM1」子集的所有列名,串連以「NM1」在setcolorder

nm1 <- c("Species", "Petal.Length") 
setcolorder(Data, c(nm1, setdiff(names(Data), nm1))) 

names(Data) 
#[1] "Species"  "Petal.Length" "Sepal.Length" "Sepal.Width" "Petal.Width" 

的便捷功能是這樣的:

setcolfirst = function(DT, ...){ 
    nm = as.character(substitute(c(...)))[-1L] 
    setcolorder(DT, c(nm, setdiff(names(DT), nm))) 
} 

setcolfirst(Data, Species, Petal.Length) 

這些列在這裏沒有引號,但擴展到字符向量很容易。

+1

啊,是的,謝謝!這使解決方法工作。我會接受你的答案,如果沒有data.table解決方案彈出(我的意思是,我們必須創建一個所有名稱的矢量首先看起來有點不典型,不?)的事實 –

+0

你需要創建這個向量的名稱,編程沒有魔法。 –

+0

好吧,你不需要'魔術'。在這裏你會在Stata中做什麼:「order Species Petal.Length」和我雖然data.table可能有一些類似的語法。但仍然感謝排除,我接受了答案。 –

1

這完全是對Akrun的解決方案的一個匆忙,使用了更多的功能分解和一個照應宏,因爲,爲什麼不呢。

我不是寫R宏的專家,所以這可能是一個天真的解決方案。

> toFront <- function(vect, ...) { 
    c(..., setdiff(vect, c(...))) 
} 
> withColnames <- function(tbl, thunk) { 
    .CN = colnames(tbl) 
    eval(substitute(thunk)) 
} 
> vect = c('c', 'd', 'e', 'a', 'b') 
> tbl = data.table(1,2,3,4,5) 
> setnames(tbl, vect) 
> tbl 
    c d e a b 
1: 1 2 3 4 5 
> withColnames(tbl, setcolorder(tbl, toFront(.CN, 'a', 'b'))) 
> tbl 
    a b c d e 
1: 4 5 1 2 3 
> 
+0

不錯,謝謝!我不知道你可以通過'...'將一個開放的參數列表傳遞給一個函數。 –