我有一个带有类列和多个值列的data.table,例如
class v1 v2 v3
1: 1 10 3 8
2: 2 2 24 7
3: 1 70 3 9
现在,对于data.table的一个子集(比如class = 1),我需要更改每个值的顺序 按照我所拥有的排列行。例如,如果排列是
3 1 2
结果应该是
class v1 v2 v3
1: 1 8 10 3
2: 2 2 24 7
3: 1 9 70 3
使用data.table实现此目的的最佳方法是什么?
如果效率更高,我可以将数据转换为矩阵。谢谢!
答案 0 :(得分:2)
这样的事情应该有效
DT <- data.table(class = sample(1:3, 10, TRUE), v1 =sample(10), v2 = sample(10), v3 = sample(10))
DT
class v1 v2 v3
1: 1 4 6 6
2: 1 7 1 5
3: 1 5 5 10
4: 1 3 8 7
5: 3 8 4 3
6: 3 9 7 9
7: 2 1 3 8
8: 2 10 10 2
9: 1 2 2 4
10: 2 6 9 1
# the neworder column contains the new permutations
swapcols <- data.table(class = 1:3, neworder = list(c(1,2,3), c(3,1,2),c(1,3,2)))
setkey(DT, class)
setkey(swapcols, class)
DT[swapcols, setNames(list(v1,v2,v3)[unlist(neworder)], c('v1','v2','v3'))]
class v1 v2 v3
1: 1 4 6 6
2: 1 7 1 5
3: 1 5 5 10
4: 1 3 8 7
5: 1 2 2 4
6: 2 8 1 3
7: 2 2 10 10
8: 2 1 6 9
9: 3 8 3 4
10: 3 9 9 7
执行像
这样的事情可能会更有效率 DT[swapcols, setcolorder(.SD, unlist(neworder))]
或
new <- DT[swapcols, list(v1,v2,v3)[unlist(neworder)]]
setnames(new, names(new), c('class', c('v1','v2','v3'))
您也可以使用:=
。
DT[J(1), `:=`(v1= v2,v2=v3,v3=v1)]
你可以尝试一些在函数中自动执行此操作的方法,但它会是eval / parse和do.call的混乱
来自Matthew(在v1.8.3中测试):
DT = data.table(class=c(1,2,1),v1=c(10,2,70),v2=c(3,24,3),v3=c(8,7,9))
DT
class v1 v2 v3
1: 1 10 3 8
2: 2 2 24 7
3: 1 70 3 9
perm = c(3,1,2)
DT[class==1,names(DT)[-1]:=.SD[,perm+1,with=FALSE]]
DT
class v1 v2 v3
1: 1 8 10 3
2: 2 2 24 7
3: 1 9 70 3
答案 1 :(得分:0)
我假设结果并不意味着包含class 2
行。
一个相当简单的解决方案:
df.new <- subset(df, class=1)
df.new <- df.new[,c(1,4,2,3)]
或者您可以一次完成所有操作:
df.new <- df[df$class==2,c("class","v3","v1","v2")]