2016-09-03 83 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