R语言 在某些情况下,当某些信息来自向量时,如何计算最小值或最大值?

4nkexdtk  于 2023-02-26  发布在  其他
关注(0)|答案(2)|浏览(99)

我正在寻找一个data.table解决方案。我想选择满足列V1/list.value〈= 0.8的最小list.value
示例如下:

list.value <- c(3.6, 3.0, 2.4, 1.8, 1.2, 0.6)
dt <- as.data.table(c(seq(from = 0.5, to = 1.0, by = 0.1)))

dt[, `:=`(ratio3.6 = V1 / 3.6)
   ][, `:=`(ratio3.0 = V1 / 3.0)
     ][, `:=`(ratio2.4 = V1 / 2.4)
       ][, `:=`(ratio1.8 = V1 / 1.8)
         ][, `:=`(ratio1.2 = V1 / 1.2)
           ][, `:=`(ratio0.6 = V1 / 0.6)]

dt

> dt

    V1  ratio3.6  ratio3.0  ratio2.4  ratio1.8  ratio1.2  ratio0.6
1: 0.5 0.1388889 0.1666667 0.2083333 0.2777778 0.4166667 0.8333333
2: 0.6 0.1666667 0.2000000 0.2500000 0.3333333 0.5000000 1.0000000
3: 0.7 0.1944444 0.2333333 0.2916667 0.3888889 0.5833333 1.1666667
4: 0.8 0.2222222 0.2666667 0.3333333 0.4444444 0.6666667 1.3333333
5: 0.9 0.2500000 0.3000000 0.3750000 0.5000000 0.7500000 1.5000000
6: 1.0 0.2777778 0.3333333 0.4166667 0.5555556 0.8333333 1.6666667

因此,我应该有一列的值是:

1: 1.2
2: 1.2
3: 1.2
4: 1.2
5: 1.2
6: 1.8

我尝试创建以下代码,但失败,

copy(dt)[, test := which.min((V1 / list.value) <= 0.8)][]

请建议解决方案,谢谢!

o3imoua4

o3imoua41#

dt[, value := sapply(V1, \(v) min(list.value[v / list.value <= 0.8])), by = .I]

      V1  ratio3.6  ratio3.0  ratio2.4  ratio1.8  ratio1.2  ratio0.6 value
   <num>     <num>     <num>     <num>     <num>     <num>     <num> <num>
1:   0.5 0.1388889 0.1666667 0.2083333 0.2777778 0.4166667 0.8333333   1.2
2:   0.6 0.1666667 0.2000000 0.2500000 0.3333333 0.5000000 1.0000000   1.2
3:   0.7 0.1944444 0.2333333 0.2916667 0.3888889 0.5833333 1.1666667   1.2
4:   0.8 0.2222222 0.2666667 0.3333333 0.4444444 0.6666667 1.3333333   1.2
5:   0.9 0.2500000 0.3000000 0.3750000 0.5000000 0.7500000 1.5000000   1.2
6:   1.0 0.2777778 0.3333333 0.4166667 0.5555556 0.8333333 1.6666667   1.8
wmtdaxz3

wmtdaxz32#

使用findInterval的解决方案。它是矢量化的,比使用分组的sapply性能更高。

dt[, test := list.value[findInterval(-V1, -list.value*0.8)]][]
#>     V1 test
#> 1: 0.5  1.2
#> 2: 0.6  1.2
#> 3: 0.7  1.2
#> 4: 0.8  1.2
#> 5: 0.9  1.2
#> 6: 1.0  1.8

或者更一般地处理未排序的list.value向量和不满足条件的情况:

dt[, test := (x <- sort(list.value, TRUE))[(findInterval(-V1, -x*0.8) - 1)%%(length(x) + 1) + 1]][]
#>     V1 test
#> 1: 0.5  1.2
#> 2: 0.6  1.2
#> 3: 0.7  1.2
#> 4: 0.8  1.2
#> 5: 0.9  1.2
#> 6: 1.0  1.8

相关问题