dplyr选择使用逻辑

Vin*_*ent 22 r dplyr

可以select在dplyr中使用逻辑向量吗?

dat <- tbl_df(mtcars)
isNum <- sapply(dat, is.numeric)
select(dat, isNum)
Run Code Online (Sandbox Code Playgroud)
select(dat, isNum)
Run Code Online (Sandbox Code Playgroud)

名称错误(sel)[未命名] < - sel [未命名]:下标作业中不允许使用NA

指数工作:select(dat,(1:ncol(dat))[isNum])为什么不合乎逻辑?

当我看到帮助函数为select时,starts_with select(dat,starts_with("m"))我认为它们可以使用逻辑...

Vin*_*ent 23

正如本建议:

select(dat, which(isNum))


Ben*_*ker 12

我的答案是:

  • no("可以选择dplyr与逻辑矢量一起使用吗?")

证据:(1)你的例子,(2)帮助页面:

...:逗号分隔的不带引号的表达式列表.您可以将变量名称视为位置.使用正值选择变量; 使用负值来删除变量.

关于逻辑向量没有说什么.抱歉.

  • 我不知道("为什么不合乎逻辑?") - "只是因为"(我认为除开发人员之外的任何人都不能真正回答这个问题).你可以提出一个功能请求......

它有点笨重,但是

select_(dat,.dots=names(isNum)[isNum])
Run Code Online (Sandbox Code Playgroud)

工作(请注意,您需要select_变量以允许使用字符向量).但是老式的好

subset(dat,select=isNum)
Run Code Online (Sandbox Code Playgroud)

似乎工作得很好(除非它没有用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)
}
Run Code Online (Sandbox Code Playgroud)

我打算建议你尝试修改这个函数来创建一个is_numeric等价物,但我不太了解底层魔法......


小智 6

正如其他答案中非常清楚地说明的那样,对您的具体问题的回答是否定的。中不能使用逻辑向量dplyr::select()

但是,在较新版本的 dplyr (v>=0.5.0) 中,有一个新函数支持将谓词函数应用于列或逻辑向量select_if()

使用select_if带有谓词功能,如下的例子可以简化为:

tbl_df(mtcars) %>% dplyr::select_if(is.numeric)
Run Code Online (Sandbox Code Playgroud)

但是,您也可以使用select_if逻辑向量。这更直接地解决了您上面的用例,如下所示:

dat <- tbl_df(mtcars)
isNum <- sapply(dat, is.numeric)
select_if(dat, isNum)
Run Code Online (Sandbox Code Playgroud)