альтернатива data.table для dplyr case_when - PullRequest
0 голосов
/ 28 октября 2018

Некоторое время назад они представили хорошую SQL-подобную альтернативу ifelse в dplyr, то есть case_when.

Есть ли в data.table эквивалент, который позволил бы вам задавать различные условияв одном операторе [] без загрузки дополнительных пакетов?

Пример:

library(dplyr)

df <- data.frame(a = c("a", "b", "a"), b = c("b", "a", "a"))

df <- df %>% mutate(
    new = case_when(
    a == "a" & b == "b" ~ "c",
    a == "b" & b == "a" ~ "d",
    TRUE ~ "e")
    )

  a b new
1 a b   c
2 b a   d
3 a a   e

Это, безусловно, будет очень полезно и сделает код более читабельным (одна из причин, почему я продолжаю использоватьdplyr в этих случаях).

Ответы [ 3 ]

0 голосов
/ 28 октября 2018

1) Если условия являются взаимоисключающими со значением по умолчанию, если все условия являются ложными, то это работает:

library(data.table)
DT <- as.data.table(df) # df is from question

DT[, new := c("e", "c", "d")[1 +
                             1 * (a == "a" & b == "b") + 
                             2 * (a == "b" & b == "a")]
]

, давая:

> DT
   a b new
1: a b   c
2: b a   d
3: a a   e

2) Если результаты условий являются числовыми, то это еще проще.Например, предположим, что вместо c и d мы хотим 10 и 17 со значением по умолчанию 3. Тогда:

library(data.table)
DT <- as.data.table(df) # df is from question

DT[, new := 3 + 
            (10 - 3) * (a == "a" & b == "b") + 
            (17 - 3) * (a == "b" & b == "a")]

3) Обратите внимание, что добавление 1-строкидостаточно для реализации этого.Предполагается, что для каждого ряда имеется хотя бы одна ИСТИНА.

when <- function(...) names(match.call()[-1])[apply(cbind(...), 1, which.max)]

# test
DT[, new := when(c = a == 'a' & b == 'b', 
                 d = a == 'b' & b == 'a', 
                 e = TRUE)]
0 голосов
/ 03 июля 2019

Вот вариант ответа @ g-grothendieck, который работает для неисключительных условий:

DT[, new := c("c", "d", "e")[
  apply(cbind(
    a == "a" & b == "b", 
    a == "b" & b == "a",
    TRUE), 1, which.max)]
  ]

DT
#    a b new
# 1: a b   c
# 2: b a   d
# 3: a a   e
0 голосов
/ 28 октября 2018

Это не совсем ответ, но слишком долго для комментария.Если это неуместно, я рад удалить сообщение.

В RStudio Community есть интересное сообщение , в котором обсуждаются варианты использования dplyr::case_when без обычных tidyverse зависимостей.

Подводя итог, можно выделить три альтернативы:

  1. Стефан Флек выделил case_when из dplyr и собрал новый пакет lest, который зависит только от base.
  2. yonicd развитый noplyr, который "обеспечивает базовые функциональные возможности dplyr и tidyr без зависимостей приливов".
  3. Боб Рудис (hrbrmstr) является создателем freebase," подобного этому "Пакета для Base R Псевдо-эквивалентов 'tidyverse «Код», который также стоит проверить.

Если вы ищете только case_when, я думаю, lest может быть привлекательным и минимальным вариантом в сочетании с data.table.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...