Я пытаюсь создать вариант pmax
/ pmin
, который работает с дополнительным параметром filter_value
в произвольном наборе столбцов, который будет определен с использованием .SD
/ .SDcols
. Первая версия функции ниже жестко кодирует значение фильтра, но работает с .SD
:
testFuncV1 <- function(...) {
cols <- list(...)
num_cols <- length(cols)
num_records <- length(cols[[1]])
max_records <- c()
for (record_num in 1:num_records) {
v <- c()
for (l in cols) {
v <- c(v, l[[record_num]])
}
filt_v <- Filter(function(x) { x <= 1 }, v)
if (length(filt_v) == 0) {
max_records <- c(max_records, NA)
} else {
max_records <- c(max_records, max(filt_v))
}
}
max_records
}
test_dt_v1 <- data.table(a = c(1,3,5), b = c(2,3,-1), c = c(-3, 5, 2))
test_dt_v1[, max_with_filter := do.call(testFuncV1, .SD), .SDcols = c('a', 'b', 'c')]
возвращается:
a b c max_with_filter
1: 1 2 -3 1
2: 3 3 5 NA
3: 5 -1 2 -1
Вторая версия функции, приведенной ниже, принимает второй параметр filter
, но я не смог заставить его работать с .SD
, и, скорее, мне пришлось передавать отдельные векторы столбцов в виде списка, чтобы получить вещи на работу:
testFuncV2 <- function(cols, filter) {
num_cols <- length(cols)
num_records <- length(cols[[1]])
max_records <- c()
for (record_num in 1:num_records) {
v <- c()
for (l in cols) {
v <- c(v, l[[record_num]])
}
filt_v <- Filter(function(x) { x <= filter }, v)
if (length(filt_v) == 0) {
max_records <- c(max_records, NA)
} else {
max_records <- c(max_records, max(filt_v))
}
}
max_records
}
test_dt_v2 <- data.table(a = c(1,3,5), b = c(2,3,-1), c = c(-3, 5, 2))
test_dt_v2[, max_with_filter := do.call(testFuncV2, list(list(test_dt_v2$a, test_dt_v2$b, test_dt_v2$c), 1))]
также возвращает:
a b c max_with_filter
1: 1 2 -3 1
2: 3 3 5 NA
3: 5 -1 2 -1
В идеале я мог бы либо выяснить подход, который работает с .SD
с использованием do.call
, либо заменить что-то, что работает с lapply
(с которым я тоже экспериментировал, но безрезультатно). Заранее спасибо!