Операции со строками в выбранных столбцах на основе подстроки в data.table
Я хотел бы применить функцию к выбранным столбцам, которые соответствуют двум различным подстрокам. Я нашел этот пост, связанный с моим вопросом, но я не мог получить ответ оттуда.
Вот воспроизводимый пример с моей неудачной попыткой. Ради этого примера я хочу сделать построчную операцию, где я суммирую значения из всех столбцов, начинающихся со строки v
и вычесть из среднего значения во всех столбцах, начиная с f
,
Обновление: предлагаемое решение должно (а) использовать :=
оператор, чтобы максимально использовать data.table
высокая производительность и (2) быть гибкими для других операций, а не mean
а также sum
, который я использовал здесь только для простоты
library(data.table)
# generate data
dt <- data.table(id= letters[1:5],
v1= 1:5,
v2= 1:5,
f1= 11:15,
f2= 11:15)
dt
#> id v1 v2 f1 f2
#> 1: a 1 1 11 11
#> 2: b 2 2 12 12
#> 3: c 3 3 13 13
#> 4: d 4 4 14 14
#> 5: e 5 5 15 15
# what I've tried
dt[, Y := sum( .SDcols=names(dt) %like% "v" ) - mean( .SDcols=names(dt) %like% "f" ) by = id]
2 ответа
Мы melt
набор данных в "длинный" формат, используя measure
аргумент, получить разницу между sum
из 'V' и mean
из 'F', сгруппированные по 'ID', присоединиться on
столбец id с исходным набором данных и назначить (:=
) 'V1' как переменная 'Y'
dt[melt(dt, measure = patterns("^v", "^f"), value.name = c("v", "f"))[
, sum(v) - mean(f), id], Y :=V1, on = .(id)]
dt
# id v1 v2 f1 f2 Y
#1: a 1 1 11 11 -9
#2: b 2 2 12 12 -8
#3: c 3 3 13 13 -7
#4: d 4 4 14 14 -6
#5: e 5 5 15 15 -5
Или другой вариант с Reduce
после создания столбцов index или 'v' и 'f'
nmv <- which(startsWith(names(dt), "v"))
nmf <- which(startsWith(names(dt), "f"))
l1 <- length(nmv)
dt[, Y := Reduce(`+`, .SD[, nmv, with = FALSE])- (Reduce(`+`, .SD[, nmf, with = FALSE])/l1)]
rowSums
а также rowMeans
в сочетании с grep
может сделать это.
dt$Y <- rowMeans(dt[,grep("f", names(dt)),with=FALSE]) - rowSums(dt[,grep("v", names(dt)),with=FALSE])