R:确定数据框中数值变量的优雅方法

时间:2011-06-22 17:51:44

标签: r vectorization

这是我用来在数据框中查找数字变量的代码:

Data <- iris
numericvars <- NULL
for (Var in names(Data)) {
    if(class(Data[,Var]) == 'integer' | class(Data[,Var]) == 'numeric') {
        numericvars <- c(numericvars,Var)
    }
}
numericvars

是否有一种不那么循环的方法呢?

4 个答案:

答案 0 :(得分:14)

这是一个非常简单的单行程sapply

sapply(Data, is.numeric)
# Sepal.Length  Sepal.Width Petal.Length  Petal.Width      Species 
#         TRUE         TRUE         TRUE         TRUE        FALSE

# is.numeric should pick up integer columns too
Data$Species <- as.integer(Data$Species)
sapply(Data, is.numeric)
# Sepal.Length  Sepal.Width Petal.Length  Petal.Width      Species 
#         TRUE         TRUE         TRUE         TRUE         TRUE

答案 1 :(得分:5)

这有点紧张:

R> sapply(colnames(iris), function(x) inherits(iris[,x], c("numeric","integer")))
Sepal.Length  Sepal.Width Petal.Length  Petal.Width      Species 
        TRUE         TRUE         TRUE         TRUE        FALSE 
R> 

答案 2 :(得分:4)

plyr中还有colwise()numcolwise()catcolwise()colwise()将对向量进行操作的函数转换为在数据帧上按列方式工作的函数。 numcolwisecatcolwise分别提供仅对数字和离散变量起作用的版本。

library(plyr)
colwise(is.numeric)(Data)

> colwise(is.numeric)(Data)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1         TRUE        TRUE         TRUE        TRUE   FALSE

答案 3 :(得分:3)

使用sapply()lapply()似乎合乎逻辑:

sapply(iris, function(x) class(x) %in% c("integer","numeric"))

给出:

> sapply(iris, function(x) class(x) %in% c("integer","numeric"))
Sepal.Length  Sepal.Width Petal.Length  Petal.Width      Species 
        TRUE         TRUE         TRUE         TRUE        FALSE

值得注意的是,在你的循环中,你在循环的每次迭代中增长numericvars向量;在R,这是一个很大的禁忌!它强制R每次复制和扩展矢量。事先分配足够的存储空间并填充物体;这意味着将numericvars创建为

numericvars <- character(length = ncol(iris))

然后在循环中做

nams <- names(iris)
for(i in seq_len(ncol(iris))) {
    if(class(iris[, i]) == 'integer' | class(iris[, i]) == 'numeric') {
        numericvars[i] <- nams[i]
    }
}

稍微多一些工作,但效率更高,但只有当迭代次数变大时才能看到它。