Выбор dplyr с помощью логического

Может ли select в dplyr использоваться с логическим вектором?

dat <- tbl_df(mtcars)
isNum <- sapply(dat, is.numeric)
select(dat, isNum)
select(dat, isNum)

Ошибка в именах (sel) [unnamed] < - sel [unnamed]:   НС не допускаются в индексированных присвоениях

Индексы работают select(dat,(1:ncol(dat))[isNum]), так почему бы не логично?

Изменить 1:

Когда я увидел вспомогательные функции для select like starts_with select(dat,starts_with("m")), я предположил, что они будут работать с логическим

Изменить 2:

select(dat, which(isNum)) работает

Ответы

Ответ 1

Мои ответы были бы следующими:

  • no ( "Можно выбрать в dplyr использовать с логическим вектором?" )

доказательства: (1) ваш пример, (2) страница справки:

...: Список некотируемых выражений, разделенных запятыми. Вы можете лечить           имена переменных, такие как позиции. Использовать положительные значения           для выбора переменных; используйте отрицательные значения для сброса переменных.

Не говорит ничего о логических векторах. К сожалению.

  • Я не знаю ( "почему не логично?" ) - "просто потому, что" (я не думаю, что кто-то, кроме разработчика, действительно мог бы ответить на это). Вы можете добавить запрос функции...

Это немного неуклюже, но

select_(dat,.dots=names(isNum)[isNum])

работает (обратите внимание, что вам нужен вариант select_, чтобы разрешить использование символьного вектора). Но хороший старомодный

subset(dat,select=isNum)

похоже, тоже работает отлично (если только он не сможет отлично играть с dplyr каким-то другим способом, о котором я не думал).

Если вы посмотрите на код dplyr:::starts_with, вы увидите, что он возвращает вектор позиций, а не логический вектор

function (vars, match, ignore.case = TRUE) 
{
    stopifnot(is.string(match), !is.na(match), nchar(match) > 
        0)
    if (ignore.case) 
        match <- tolower(match)
    n <- nchar(match)
    if (ignore.case) 
        vars <- tolower(vars)
    which(substr(vars, 1, n) == match)
}

Я собирался предположить, что вы попытаетесь изменить эту функцию, чтобы создать эквивалент is_numeric, но я недостаточно хорошо понимаю базовую магию...

Ответ 2

Как Бен предложил:

select(dat, which(isNum))

Ответ 3

Как ясно сказано в других ответах, ответ на ваш конкретный вопрос: нет. Вы не можете использовать логический вектор в dplyr::select().

Однако в более поздних версиях dplyr (v >= 0.5.0) существует новая функция, которая поддерживает использование предикатной функции, применяемой к столбцам или логическому вектору: select_if().

Используя select_if с функцией предиката, ваш пример можно упростить следующим образом:

tbl_df(mtcars) %>% dplyr::select_if(is.numeric)

Но вы также можете использовать select_if с логическим вектором. Это более непосредственно касается вашего примера использования выше, который будет выглядеть следующим образом:

dat <- tbl_df(mtcars)
isNum <- sapply(dat, is.numeric)
select_if(dat, isNum)