从数据框中仅选择数字列


Answers:


288

编辑:更新为避免使用不当建议sapply

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

nums <- unlist(lapply(x, is.numeric))  

然后是标准子集

x[ , nums]

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

对于更惯用的现代R,我现在建议

x[ , purrr::map_lgl(x, is.numeric)]

较少的编码,较少的反映R的特殊问题,并且更直接,更健壮,可以在数据库后端的小标题上使用:

dplyr::select_if(x, is.numeric)

10
x[nums]x[sapply(x,is.numeric)]也可以。他们总是回来data.frame。比较x[1]vs- x[,1]第一个是data.frame,第二个是向量。如果要防止转换,则必须使用x[, 1, drop=FALSE]
马雷克(Marek)

有什么办法只能选择连续数据吗?此方法返回连续以及整数。
2016年

如果没有数字列,则会出现以下错误undefined columns selected。你如何避免呢?
Yohan Obadia

@SoilSciGuy连续数据应为数字。也许您有数字形式的因子数据?您应该打开一个新问题。
布兰登·贝特尔森

1
@YohanObadia您可以使用tryCatch()来处理此问题。请考虑打开一个新问题。
布兰登·贝特尔森

79

dplyr包的select_if()函数是一个优雅的解决方案:

library("dplyr")
select_if(x, is.numeric)

44

Filter() 来自基本软件包的代码是该用例的理想功能:您只需编写代码:

Filter(is.numeric, x)

它也比select_if()

library(microbenchmark)
microbenchmark(
    dplyr::select_if(mtcars, is.numeric),
    Filter(is.numeric, mtcars)
)

(在我的计算机上)返回的中位数为60微秒Filter,返回为select_if21000 微秒(快350倍)。


当不存在数字列时,此解决方案不会失败。使用它有什么缺点吗?
bli

过滤器仅适用于数据框的行,而不适用于列。因此,此解决方案将无法给出正确的结果。
迈克尔(Michael)

4
@Michael不要混淆来自基本软件包的过滤器和来自dplyr软件包的过滤器!
凯文·扎卡(

1
@bli我看不到使用过滤器的任何缺点。它的输入是一个data.frame对象,它返回一个data.frame
Kevin Zarca

只是在这里供参考:在这里Filter()行不通的是替换,例如Filter(is.numeric,iris) <- 0.5*Filter(is.numeric,iris)行不通。
Mobeus Zoom

8

如果您只对列名感兴趣,请使用this:

names(dplyr::select_if(train,is.numeric))



2

库PCAmixdata具有functon splitmix,它可以分割给定数据帧“ YourDataframe”的定量(数值数据)和定性(类别数据),如下所示:

install.packages("PCAmixdata")
library(PCAmixdata)
split <- splitmix(YourDataframe)
X1 <- split$X.quanti(Gives numerical columns in the dataset) 
X2 <- split$X.quali (Gives categorical columns in the dataset)

2

另一种方法可能如下:

#extracting numeric columns from iris datset
(iris[sapply(iris, is.numeric)])

1
嗨,Ayushi,您可能对此不满意,因为它是对第一个答案的重复,但是此方法存在一些已确定的问题。看看第一个答案中的评论,您会明白我的意思。
布兰登·贝特尔森

1

如果因子变量很多,则可以使用select_if函数。安装dplyr软件包。有许多功能可以通过满足条件来分离数据。您可以设置条件。

这样使用。

categorical<-select_if(df,is.factor)
str(categorical)

2
看起来像这个早先答案的副本stackoverflow.com/a/40808873/170352
Brandon Bertelsen

0

这不能直接回答问题,但可能非常有用,特别是如果您想要除id列和因变量之外的所有数字列之类的东西。

numeric_cols <- sapply(dataframe, is.numeric) %>% which %>% 
                   names %>% setdiff(., c("id_variable", "dep_var"))

dataframe %<>% dplyr::mutate_at(numeric_cols, function(x) your_function(x))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.