Добавить максимальный столбец, используя переменную - PullRequest
0 голосов
/ 12 сентября 2018

Я пытаюсь сделать то же самое, что и этот вопрос: Добавить максимальное значение в новый столбец в R , однако я хочу передать переменную вместо имени столбца напрямую, поэтому я не• жестко закодируйте имя столбца в формулу.

Пример кода:

a <- c(1,1,2,2,3,3)  
b <- c(1,3,5,9,4,NA)
d <- data.table(a, b)
d

a b
1 1
1 3
2 5
2 9
3 4
3 NA

Я могу получить это:

a b max_b
1 1 3
1 3 3
2 5 9
2 9 9
3 4 4
3 NA 4

Путем жесткого кодирования: setDT(d)[, max_b:= max(b, na.rm = T), a]но я хотел бы сделать что-то вроде этого:

cn <- "b"
setDT(d)[, paste0("max_", cn):= max(cn, na.rm = T), a]

Однако, это не работает, потому что внутри max() он оценивает максимум символа вместо столбца.И он оценивается в столбец с именем max_b, который содержит значение b, поскольку max("b") = "b".Я понимаю, почему это происходит, я просто не знаю обходной путь.

Какое решение для этого?

Примечание: указанный выше вопрос стека, который я пометил, был помечен как дубликат и закрыт, но я выбрал этот вопрос, потому что я использую принятый ответиз этого в моем коде.Я также не согласен на 100%, что это в любом случае дублирующий вопрос.

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Один из вариантов - указать переменную в .SDcols, а затем применить функцию к .SD (Подмножество Data.table).

d[, paste0("max_", cn) := lapply(.SD, max, na.rm = TRUE), by = a, .SDcols = cn]
d
#   a  b max_b
#1: 1  1     3
#2: 1  3     3
#3: 2  5     9
#4: 2  9     9
#5: 3  4     4
#6: 3 NA     4

Другой вариант - преобразование в символ и затем eval uation

d[, paste0("max_", cn) := max(eval(as.symbol(cn)), na.rm = TRUE), by = a]
0 голосов
/ 12 сентября 2018

Попробуйте setDT(d)[, paste0("max_", cn) := eval(parse(text = max(eval(parse(text = cn))))), a]

# output
   a b max_b
1: 1 1     3
2: 1 3     3
3: 2 5     9
4: 2 9     9
5: 3 4     4

# example with missing values
a <- c(1,1,2,2,3,3)  
b <- c(1,3,5,9,4,NA)
d <- data.table(a, b)
cn <- "b"
setDT(d)[, paste0("max_", cn) := eval(parse(text = max(eval(parse(text = cn)),
                                                       na.rm = TRUE))), a]
#output
   a  b max_b
1: 1  1     3
2: 1  3     3
3: 2  5     9
4: 2  9     9
5: 3  4     4
6: 3 NA     4
...