2017-03-02 62 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