根据与dplyr :: select兼容的类/类型选择列

拉珀斯特

实际问题

如何定义一个选择帮助器,该选择器根据列的类/类型来选择列并且还与dplyr的体系结构兼容

尽职调查

我看过https://cran.r-project.org/web/packages/dplyr/vignettes/introduction.html及其帮助,dplyr::select_helpers但没有找到让我根据类/类型进行选择的内容

引入一些变化的WRT类/类型:

dat <- mtcars
dat <- dat %>% mutate(
  mpg = as.character(mpg),
  wt = as.factor(wt),
  vs = as.character(vs)
)

简而言之,我想对R中所有可能的类/类型(及其组合)使用通用方法

dat[ , sapply(dat, is.character)]
# mpg    wt vs
# 1    21  2.62  0
# 2    21 2.875  0
# 3  22.8  2.32  1
# 4  21.4 3.215  1

基于基于列类型的数据框中的子集变量,我可以这样做:

select_on_class <- function(.data, cls = "numeric") {
  dat[ , names(.data)[sapply(.data,
    function(vec, clss) class(vec) %in% clss, clss = cls)]]
}
dat %>% select_on_class(c("character", "factor"))
# mpg    wt vs
# 1    21  2.62  0
# 2    21 2.875  0
# 3  22.8  2.32  1
# 4  21.4 3.215  1

但是我希望能够在对的调用中使用它dplyr::select,因此我尝试了以下操作:

has_class <- function(.data, cls = "numeric") {
  nms <- names(.data)[sapply(.data,
    function(vec, clss) class(vec) %in% clss, clss = cls)]
  sapply(nms, as.name)
}
dat %>% has_class(c("character", "factor"))
# $mpg
# mpg
# 
# $wt
# wt
# 
# $vs
# vs

问题是sapply(nms, as.name)返回a list,并且不能很好地与的内部配合使用select(顺便说一句,我还不完全了解):

dat %>% select(has_class(c("character", "factor")))
# Error: All select() inputs must resolve to integer column positions.
# The following do not:
#   *  has_class("character")

dat %>% select_(has_class(c("character", "factor")))
# Error in UseMethod("as.lazy") : 
#   no applicable method for 'as.lazy' applied to an object of class "list"

编辑

根据使用的答案,select_if我尝试进行概括并陷入困境:

has_class <- function(.data, cls) {
  sapply(.data, function(vec, clss) class(vec) %in% clss, clss = cls)
}
dat %>% has_class(c("character", "factor"))
# mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
# TRUE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE
dat %>% select_if(has_class, c("character", "factor"))
# Error in vapply(tbl, p, logical(1), ...) : values must be length 1,
# but FUN(X[[1]]) result is length 32

在AFAIU中,这些.predicate函数只需要返回一个逻辑向量(has_class确实如此),并且我可以.predicate通过...(我确实)将其他参数传递给这些函数那么,我仍然在哪里出错?

wjchulme

我想dplyr::select_if()可能就是您要寻找的。例如

dat <- mtcars %>% 
       mutate(mpg = as.character(mpg),
              wt = as.character(wt),
              vs = as.character(vs)
       ) %>% 
       select_if(is.character)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章