仅选择数据框中的数字列

Bra*_*sen 165 r

假设你有一个像这样的data.frame:

x <- data.frame(v1=1:20,v2=1:20,v3=1:20,v4=letters[1:20])
Run Code Online (Sandbox Code Playgroud)

您如何仅选择x中的数字列?

mds*_*ner 264

编辑:更新,以避免使用不明智的sapply.

由于数据框是一个列表,我们可以使用list-apply函数:

nums <- unlist(lapply(x, is.numeric))  
Run Code Online (Sandbox Code Playgroud)

然后是标准子集

x[ , nums]

## don't use sapply, even though it's less code
## nums <- sapply(x, is.numeric)
Run Code Online (Sandbox Code Playgroud)

对于一个更现代的现代R我现在推荐

x[ , purrr::map_lgl(x, is.numeric)]
Run Code Online (Sandbox Code Playgroud)

更少的代码,更少反映R的特殊怪癖,更简单,更强大,可用于数据库后端元素:

dplyr::select_if(x, is.numeric)
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,我发现就像你发布的那样x [,sapply(x,is.numeric)] (9认同)
  • `x [nums]`或`x [sapply(x,is.numeric)]`也适用.他们总是返回`data.frame`.比较`x [1]`vs`x [,1]` - 首先是`data.frame`,第二个是向量.如果想要阻止转换,那么必须使用`x [,1,drop = FALSE]`. (8认同)

Sha*_*ron 69

dplyr软件包的select_if(功能是一个优雅的解决方案:

library("dplyr")
select_if(x, is.numeric)
Run Code Online (Sandbox Code Playgroud)

  • 选择(其中(is.numeric))https://tidyselect.r-lib.org/reference/where.html (3认同)
  • select_if()仍出现在当前函数参考中,网址为https://dplyr.tidyverse.org/reference/index.html。您可能正在考虑不推荐使用select_()。 (2认同)

Kev*_*rca 35

Filter() 从基础包是这个用例的完美功能:你只需要编码:

Filter(is.numeric, x)
Run Code Online (Sandbox Code Playgroud)

它也比以下快得多select_if():

library(microbenchmark)
microbenchmark(
    dplyr::select_if(mtcars, is.numeric),
    Filter(is.numeric, mtcars)
)
Run Code Online (Sandbox Code Playgroud)

返回(在我的计算机上)中位数为60微秒Filter,和21 000微秒select_if(更快350倍).

  • @Michael不要混淆基本软件包中的Filter和dplyr软件包中的filter! (2认同)

Sve*_*enB 9

iris %>% dplyr::select(where(is.numeric)) #as per most recent updates
Run Code Online (Sandbox Code Playgroud)

另一种选择purrr是否定discard函数:

iris %>% purrr::discard(~!is.numeric(.))
Run Code Online (Sandbox Code Playgroud)

如果您想要数字列的名称,您可以添加namescolnames

iris %>% purrr::discard(~!is.numeric(.)) %>% names
Run Code Online (Sandbox Code Playgroud)


Enr*_*ero 8

这是其他答案的替代代码:

x[, sapply(x, class) == "numeric"]
Run Code Online (Sandbox Code Playgroud)

data.table

x[, lapply(x, is.numeric) == TRUE, with = FALSE]
Run Code Online (Sandbox Code Playgroud)

  • 这更多是对所选答案的评论,而不是唯一的答案。 (3认同)
  • 列可以有多个类。 (2认同)

use*_*757 6

如果您只对列名感兴趣,请使用以下命令:

names(dplyr::select_if(train,is.numeric))
Run Code Online (Sandbox Code Playgroud)


小智 6

library(purrr)
x <- x %>% keep(is.numeric)
Run Code Online (Sandbox Code Playgroud)