2016-09-03 42 views
-1

我有列名以下data.table:值作为data.table

dat<-data.table(Y=as.factor(c("a","b","a")),"a"=c(1,2,3),"b"=c(3,2,1)) 

它看起来像:

Y a b 
1: a 1 3 
2: b 2 2 
3: a 3 1 

我想是减去列所指示的值Y的值是1.例如第一行的Y值为“a”,所以第一行的“a”列的值应该减1。 结果应该是:

Y a b 
1: a 0 3 
2: b 2 1 
3: a 2 1 

这可能吗?如果是,如何?谢谢!

回答

4

使用自连接和get:。

for (yval in dat[ , unique(Y)]){ 
    dat[yval, (yval) := get(yval) - 1L, on = "Y"] 
} 
dat[] 
# Y a b 
# 1: a 0 3 
# 2: b 2 1 
# 3: a 2 1 
2

我们可以用melt/dcast来做到这一点。 melt创建行序列('N')为'long'格式后的数据集,从'值'列中减去1,其中'Y'和'变量'元素相等,将输出值赋值为'value',然后dcast“长”格式,以“宽”

dcast(melt(dat[, N := 1:.N], id.var = c("Y", "N"))[Y==variable, 
    value := value -1], N + Y ~variable, value.var = "value")[, N := NULL][] 
# Y a b 
#1: a 0 3 
#2: b 2 1 
#3: a 2 1 
+1

请注意,这将需要一个副本来保存对象(无论如何+1) – MichaelChirico

0

首先的应用功能,使实际的转型,我们需要通过行,然后申请使用第一个元素来命名第二个元素来访问和重写。出于某种原因,我在中访问的值和b是字符串,所以我使用as.numeric将它们转换为数字。我不知道在data.table中这是否正常,或者因为我没有正常使用data.table s,所以在一个使用apply语句的结果是正常的。

tformDat <- apply(dat, 1, function(x) {x[x[1]] <- as.numeric(x[x[1]]) - 1;x}) 

那么你需要重新回到原来的data.table格式

data.table(t(tformDat)) 

整个事情可以在一个线路来完成。

data.table(t(apply(dat, 1, function(x) {x[x[1]] <- as.numeric(x[x[1]]) - 1;x}))) 
+2

这将强制所有列为'character' – MichaelChirico