循环data.table中每列的最大值

问题描述 投票:0回答:1

我遇到以下问题。

我想构建一个具有 data.table 每一列的最大值的向量 - 但它不起作用,输出向量只是我的 for 循环的索引序列。

library(data.table)
d <- data.frame(matrix(runif(100, 1, 100), ncol = 10))  # Example dataframe
setDT(d) # to create a data.table

max_values <- numeric(length = ncol(d))

# Loop through each column
for (i in 1:ncol(d)) {
  max_values[i] <- max(d[, c(i)])
}

所以我的 max_values 向量由数字 1:10 组成,但不是最大值。

提前谢谢您。

r data.table
1个回答
2
投票

请参阅这个问答另一个,了解为什么

c(i)
不起作用。

for
循环发挥作用的几种方法:

for (i in 1:ncol(d)) max_values[i] <- max(d[, ..i])
for (i in 1:ncol(d)) max_values[i] <- max(d[[i]])

或者我们可以这样做:

max_values <- d[, sapply(.SD, max)]

甚至:

max_values <- Rfast::colMaxs(as.matrix(d), TRUE)

使用哪个取决于

d
的大小和形状(以及可用内存)。例如:

library(Rfast)
library(bench)

x <- runif(1e6)

lapply(
  lapply(1:5, \(i) as.data.table(matrix(x, 10^i))),
  \(dt) mark(
    {y <- numeric(ncol(dt)); for (i in 1:ncol(dt)) y[i] <- max(dt[[i]]); y},
    unname(dt[,sapply(.SD, max)]),
    colMaxs(as.matrix(dt), TRUE)
  )
)

结果:

#> [[1]]
#> # A tibble: 3 × 13
#>   expression     min  median `itr/sec` mem_alloc `gc/sec` n_itr  n_gc total_time
#>   <bch:expr> <bch:t> <bch:t>     <dbl> <bch:byt>    <dbl> <int> <dbl>   <bch:tm>
#> 1 { y <- nu… 645.2ms 645.2ms    1.55     783.5KB   12.4       1     8    645.2ms
#> 2 unname(dt…   22.8s   22.8s    0.0439    29.1MB    0.570     1    13      22.8s
#> 3 colMaxs(a… 548.2ms 548.2ms    1.82      10.8MB   10.9       1     6    548.2ms
#> 
#> [[2]]
#> # A tibble: 3 × 13
#>   expression     min  median `itr/sec` mem_alloc `gc/sec` n_itr  n_gc total_time
#>   <bch:expr> <bch:t> <bch:t>     <dbl> <bch:byt>    <dbl> <int> <dbl>   <bch:tm>
#> 1 { y <- nu…  53.7ms  63.1ms     16.1    78.17KB    14.4      9     8      557ms
#> 2 unname(dt… 328.5ms 334.1ms      2.99    2.81MB     4.49     2     3      668ms
#> 3 colMaxs(a…  45.5ms  59.1ms     17.2     7.94MB     9.58     9     5      522ms
#> 
#> [[3]]
#> # A tibble: 3 × 13
#>   expression     min  median `itr/sec` mem_alloc `gc/sec` n_itr  n_gc total_time
#>   <bch:expr> <bch:t> <bch:t>     <dbl> <bch:byt>    <dbl> <int> <dbl>   <bch:tm>
#> 1 { y <- nu…   5.1ms  5.51ms     163.     7.86KB     18.4    62     7      380ms
#> 2 unname(dt… 12.97ms 13.97ms      71.7  327.49KB     10.6    27     4      377ms
#> 3 colMaxs(a…  7.42ms  8.39ms     102.     7.66MB     18.3    39     7      383ms
#> 
#> [[4]]
#> # A tibble: 3 × 13
#>   expression      min median `itr/sec` mem_alloc `gc/sec` n_itr  n_gc total_time
#>   <bch:expr>   <bch:> <bch:>     <dbl> <bch:byt>    <dbl> <int> <dbl>   <bch:tm>
#> 1 { y <- nume… 1.33ms 2.18ms      464.      848B     4.33   214     2      462ms
#> 2 unname(dt[,… 2.14ms 3.44ms      283.   77.57KB     4.28   132     2      467ms
#> 3 colMaxs(as.… 4.83ms 5.33ms      186.    7.63MB    30.9     60    10      323ms
#> 
#> [[5]]
#> # A tibble: 3 × 13
#>   expression      min median `itr/sec` mem_alloc `gc/sec` n_itr  n_gc total_time
#>   <bch:expr> <bch:tm> <bch:>     <dbl> <bch:byt>    <dbl> <int> <dbl>   <bch:tm>
#> 1 { y <- nu…  948.4µs 1.59ms      615.        0B     0      308     0      501ms
#> 2 unname(dt…   1.42ms 2.07ms      483.   49.02KB     2.06   235     1      486ms
#> 3 colMaxs(a…   3.38ms 4.35ms      228.    7.63MB    36.4     69    11      302ms

还有一个:

dt <- as.data.table(matrix(runif(1e7), 1e6))
bench::mark(
  {y <- numeric(ncol(dt)); for (i in 1:ncol(dt)) y[i] <- max(dt[[i]]); y},
  unname(dt[,sapply(.SD, max)]),
  colMaxs(as.matrix(dt), TRUE)
)
#> # A tibble: 3 × 6
#>   expression                             min median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr>                          <bch:> <bch:>     <dbl> <bch:byt>    <dbl>
#> 1 { y <- numeric(ncol(dt)) for (i in… 11.8ms   13ms      76.0   56.23KB     2.05
#> 2 unname(dt[, sapply(.SD, max)])      10.2ms 11.2ms      88.5    1.64MB     2.01
#> 3 colMaxs(as.matrix(dt), TRUE)        34.2ms 34.9ms      28.3    76.4MB    39.6
© www.soinside.com 2019 - 2024. All rights reserved.