生成上限值为 data.table 的列
generate column with capped values in data.table
我有一个 data.table 类似于下面的:
| ID | C1 | C2 | C3 |
| 1 | 1 | 20 | 400 |
| 2 | 0 | 15 | 500 |
| 3 | 0 | 2 | 350 |
| 4 | 1 | 4 | 402 |
| 5 | 1 | 8 | 333 |
我想生成一个新列 "CALC" 并应用如下函数:
func <- function(a, b, c){
pol <- a*b-0.01*c
value <- min(max(pol, 0), 5)
}
我认为它会给我的是每行中的 pol 解决方案,上限为 0 和 5。所以,而不是
| ID | C1 | C2 | C3 | CALC |
| 1 | 1 | 20 | 400 | 16 |
| 2 | 0 | 15 | 500 | -5 |
| 3 | 0 | 2 | 350 | -3.5 |
| 4 | 1 | 4 | 402 | -0.02 |
| 5 | 1 | 8 | 333 | 4.67 |
应该return
| ID | C1 | C2 | C3 | CALC |
| 1 | 1 | 20 | 400 | 5 |
| 2 | 0 | 15 | 500 | 0 |
| 3 | 0 | 2 | 350 | 0 |
| 4 | 1 | 4 | 402 | 0 |
| 5 | 1 | 8 | 333 | 4.67 |
但是,它给出的是以下 dt:
| ID | C1 | C2 | C3 | CALC |
| 1 | 1 | 20 | 400 | 5 |
| 2 | 0 | 15 | 500 | 5 |
| 3 | 0 | 2 | 350 | 5 |
| 4 | 1 | 4 | 402 | 5 |
| 5 | 1 | 8 | 333 | 5 |
因此,如果我没记错的话,它会获取列中值的最大值(以 5 为上限)并沿列放入。不是我的意图,这将单独获得每一行的最大值。
有什么"easy"方法可以解决吗?原来的 dt 更复杂,所以不可能简单地做 dt[, CALC := func(C1, C2, C3), by="ID"]
,因为它应该像 by=.(GROUP1, GROUP2, ID)
,我很确定它必须更简单。也许函数本身有一个简单的方法?
非常感谢您的宝贵时间。
您需要使用 pmin
和 pmax
func <- function(a, b, c){
pol <- a*b-0.01*c
pmin(pmax(pol, 0), 5)
}
transform(dat,s=func(C1,C2,C3))
ID C1 C2 C3 s
1 1 1 20 400 5.00
2 2 0 15 500 0.00
3 3 0 2 350 0.00
4 4 1 4 402 0.00
5 5 1 8 333 4.67
setDT(dat)[,CALC:=func(C1,C2,C3)]
dat
ID C1 C2 C3 CALC
1: 1 1 20 400 5.00
2: 2 0 15 500 0.00
3: 3 0 2 350 0.00
4: 4 1 4 402 0.00
5: 5 1 8 333 4.67
我有一个 data.table 类似于下面的:
| ID | C1 | C2 | C3 |
| 1 | 1 | 20 | 400 |
| 2 | 0 | 15 | 500 |
| 3 | 0 | 2 | 350 |
| 4 | 1 | 4 | 402 |
| 5 | 1 | 8 | 333 |
我想生成一个新列 "CALC" 并应用如下函数:
func <- function(a, b, c){
pol <- a*b-0.01*c
value <- min(max(pol, 0), 5)
}
我认为它会给我的是每行中的 pol 解决方案,上限为 0 和 5。所以,而不是
| ID | C1 | C2 | C3 | CALC |
| 1 | 1 | 20 | 400 | 16 |
| 2 | 0 | 15 | 500 | -5 |
| 3 | 0 | 2 | 350 | -3.5 |
| 4 | 1 | 4 | 402 | -0.02 |
| 5 | 1 | 8 | 333 | 4.67 |
应该return
| ID | C1 | C2 | C3 | CALC |
| 1 | 1 | 20 | 400 | 5 |
| 2 | 0 | 15 | 500 | 0 |
| 3 | 0 | 2 | 350 | 0 |
| 4 | 1 | 4 | 402 | 0 |
| 5 | 1 | 8 | 333 | 4.67 |
但是,它给出的是以下 dt:
| ID | C1 | C2 | C3 | CALC |
| 1 | 1 | 20 | 400 | 5 |
| 2 | 0 | 15 | 500 | 5 |
| 3 | 0 | 2 | 350 | 5 |
| 4 | 1 | 4 | 402 | 5 |
| 5 | 1 | 8 | 333 | 5 |
因此,如果我没记错的话,它会获取列中值的最大值(以 5 为上限)并沿列放入。不是我的意图,这将单独获得每一行的最大值。
有什么"easy"方法可以解决吗?原来的 dt 更复杂,所以不可能简单地做 dt[, CALC := func(C1, C2, C3), by="ID"]
,因为它应该像 by=.(GROUP1, GROUP2, ID)
,我很确定它必须更简单。也许函数本身有一个简单的方法?
非常感谢您的宝贵时间。
您需要使用 pmin
和 pmax
func <- function(a, b, c){
pol <- a*b-0.01*c
pmin(pmax(pol, 0), 5)
}
transform(dat,s=func(C1,C2,C3))
ID C1 C2 C3 s
1 1 1 20 400 5.00
2 2 0 15 500 0.00
3 3 0 2 350 0.00
4 4 1 4 402 0.00
5 5 1 8 333 4.67
setDT(dat)[,CALC:=func(C1,C2,C3)]
dat
ID C1 C2 C3 CALC
1: 1 1 20 400 5.00
2: 2 0 15 500 0.00
3: 3 0 2 350 0.00
4: 4 1 4 402 0.00
5: 5 1 8 333 4.67