2016-04-21 70 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

不错,谢谢!我不知道你可以通过'...'将一个开放的参数列表传递给一个函数。 –