You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在R的data.table中用do.call与.SD实现带过滤参数的pmax/pmin变体

Hey there! Let's build that flexible pmax/pmin variant you're after—one that works seamlessly with data.table's .SD/.SDcols and lets you specify a custom filter_value instead of hardcoding it.

First, let's break down the limitations of your testFuncV1: nested loops are slow in R (especially with large datasets), the filter value is fixed, and it doesn't integrate cleanly with .SD. Here's a polished, efficient solution:

Core Functions (Vectorized, .SD-Friendly)

These functions replace your target filter value with NA (so it gets excluded from the max/min calculation) and use vectorized operations for speed:

# Filtered row-wise max function
filter_pmax <- function(.SD, filter_value, na.rm = FALSE) {
  # Convert .SD to matrix for fast row operations
  sd_mat <- as.matrix(.SD)
  # Replace filter_value with NA to exclude it
  sd_mat[sd_mat == filter_value] <- NA
  # Calculate row-wise max, handling NAs as needed
  apply(sd_mat, 1, \(row) pmax(row, na.rm = na.rm))
}

# Filtered row-wise min function
filter_pmin <- function(.SD, filter_value, na.rm = FALSE) {
  sd_mat <- as.matrix(.SD)
  sd_mat[sd_mat == filter_value] <- NA
  apply(sd_mat, 1, \(row) pmin(row, na.rm = na.rm))
}

How to Use with data.table

Let's test this with a sample dataset:

library(data.table)
dt <- data.table(
  id = 1:5,
  temp1 = c(22, 30, 25, 30, 18),
  temp2 = c(30, 21, 30, 19, 24),
  temp3 = c(27, 30, 22, 25, 30)
)

Suppose we want the row-wise max of temp1 and temp3, excluding any value equal to 30:

dt[, filtered_temp_max := filter_pmax(.SD, filter_value = 30, na.rm = TRUE), .SDcols = c("temp1", "temp3")]

Here's the result:

id temp1 temp2 temp3 filtered_temp_max
1:  1    22    30    27                27
2:  2    30    21    30               NA  # Both values were 30, no valid data left
3:  3    25    30    22                25
4:  4    30    19    25                25
5:  5    18    24    30                18

Key Upgrades Over Your V1

  • No More Loops: Vectorized operations are way faster than nested for loops, especially with big data.
  • Custom Filter Value: Pass any filter_value you want instead of hardcoding it.
  • NA Control: The na.rm parameter matches base R's pmax/pmin behavior, so you choose whether to ignore NAs (including those we created from the filter value).
  • .SD Ready: Built to work directly with data.table's .SD and .SDcols, so you can target any subset of columns easily.

Even Faster Version (For Large Datasets)

If you're working with huge tables, use matrixStats's optimized rowMaxs/rowMins functions (they're implemented in C):

library(matrixStats)

filter_pmax_fast <- function(.SD, filter_value, na.rm = FALSE) {
  sd_mat <- as.matrix(.SD)
  sd_mat[sd_mat == filter_value] <- NA
  rowMaxs(sd_mat, na.rm = na.rm)
}

filter_pmin_fast <- function(.SD, filter_value, na.rm = FALSE) {
  sd_mat <- as.matrix(.SD)
  sd_mat[sd_mat == filter_value] <- NA
  rowMins(sd_mat, na.rm = na.rm)
}

Quick Notes

  • To filter multiple values at once, change the replacement line to sd_mat[sd_mat %in% filter_value] <- NA (just pass a vector for filter_value).
  • Ensure your .SD columns are numeric—pmax/pmin only works with numeric data, so non-numeric columns will throw an error (which is expected behavior).

内容的提问来源于stack exchange,提问作者AvocadoRivalry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:04:48