2017-03-02 63 views
1

我在data.table列和單個值(n)上有一組非負整數值,我需要將其減去。用條件在多個數據錶行中減去單個值

如果n的值是例如34,則從data.table列中的所有值中減去的總數將需要是34(即,不是從每個值中減去34)。

但是有一些限制。如果存在一個0值,那麼這個值必須保持爲0,如果任何值大於0,那麼它不能低於1.最後,我想減法是隨機的,所以(如果在數學上可能),我沒有得到每次都有相同的結果。

下面是一些示例數據:

library(data.table) 
n = 34 
dt1 <- data.table(SIZE = c(12,0,28,3,42,57)) 

這些是輸出兩個實例中,基於所述樣本數據,將滿足我的標準:

s1 <- data.table(SIZE = c(1,0,18,1,40,48)) 
s2 <- data.table(SIZE = c(2,0,24,3,42,37)) 
+0

這是不明確的。如果條目是0.5,會怎麼樣?這是零和小於一,所以你要*提高*它?如果你的標準不可行,你會怎麼做?如果所有的數字都是非負整數,這使得它可行,但你想要指定... – Frank

+1

@Frank對不起。我的方案中的數字都是非負整數。如果有人在將來尋找類似問題的解決方案,我已經澄清了這個問題。另外,在我的情況下,如果操作不可行,那麼它在獲得解決方案所需的階段之前就會被跳過。 – Chris

回答

1

這是drawing from an urn無需更換。每一行相關的「球」的數量是

dt1[, pmax(SIZE-1L, 0)] 
# [1] 11 0 27 2 41 56 

如果有少於n球,你的問題是不可行的。否則,你可以使用sample

set.seed(1) 
dt1[, sample(rep(.I, pmax(SIZE-1L, 0)), n)] 
# [1] 3 5 5 6 3 6 6 6 6 1 6 3 6 5 6 5 6 6 5 6 6 3 5 3 3 5 1 5 6 6 5 5 6 3 

若要將此平局...

set.seed(1) 
draw <- dt1[, .(r = sample(rep(.I, pmax(SIZE-1L, 0)), n))][, .N, by=r] 
dt1[, NEW_SIZE := SIZE ][ draw$r, NEW_SIZE := SIZE - draw$N ] 
# SIZE NEW_SIZE 
# 1: 12  10 
# 2: 0  0 
# 3: 28  21 
# 4: 3  3 
# 5: 42  32 
# 6: 57  42 

# verify 
dt1[, sum(SIZE - NEW_SIZE)] == n 
# [1] TRUE 
+0

我將繼續並假設OP正在處理計數(非負整數)。 – Frank

+1

謝謝你的回答。這正是我所追求的。另外,你的假設是正確的。 – Chris