dplyr选择使用逻辑

时间:2014-11-11 21:46:46

标签: r dplyr

dplyr中的select可以与逻辑向量一起使用吗?

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

名称错误(sel)[未命名]&lt; - sel [未命名]:     订阅作业中不允许使用NA

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

当我看到像starts_with select(dat,starts_with("m"))这样的选择的辅助函数时,我认为它们可以使用逻辑...

3 个答案:

答案 0 :(得分:21)

正如Ben所说:

select(dat, which(isNum))

答案 1 :(得分:12)

我的答案是:

  • 否(“可以在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 :(得分:3)

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

但是,在更新版本的dplyr(v&gt; = 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)