如何检查任何非有限的data.frame

时间:2011-11-17 19:29:14

标签: r

我想检查data.frame是否有任何非有限元素。

这似乎评估了每一列,每个列返回FALSE(我猜测它将data.frame作为列表进行评估):

any( !is.finite( x ) )

我不明白为什么这与上面的行为有所不同,但如果只是检查NAs它会正常工作:

any( !is.na( x ) )

我希望解决方案尽可能高效。我意识到我可以做......

any( !is.finite( as.matrix( x ) ) )

4 个答案:

答案 0 :(得分:17)

如果您输入methods(is.na),您会看到它有一个data.frame方法,这可能解释了为什么它按照您期望的方式工作,is.finite没有。通常的解决方案是自己写一个,因为它只有一行。这样的事可能,

is.finite.data.frame <- function(obj){
    sapply(obj,FUN = function(x) all(is.finite(x)))
}

答案 1 :(得分:7)

我假设你得到的错误如下:

> any( is.infinite( z ) )
Error in is.infinite(z) : default method not implemented for type 'list'

此错误是因为is.infinite()is.finite()函数未使用data.frames的方法实现。 is.na()函数确实有data.frame方法。

解决此问题的方法是将apply()函数添加到data.frame中的每一行,每列或每个元素。以下是使用sapply()is.infinite()函数应用于每个元素的示例:

x <- c(1:10, NA)
y <- c(1:11)
z <- data.frame(x,y)
any( sapply(z, is.infinite) )
 ## or

any( ! sapply(z, is.finite) )

答案 2 :(得分:4)

只有as.matrix只有数字列时,您的调用data.frame解决方案才有效。否则,矩阵通常会变成一个字符矩阵,结果在任何地方都是假的......

@joran有一个很好的方法,但你会遇到因子列的问题,除非为因素添加一个方法等...

is.finite(letters[1:3])         # FALSE - OK
is.finite(factor(letters[1:3])) # TRUE - WRONG!!

is.finite.factor <- function(obj){
    logical(length(obj))
}

is.finite(factor(letters[1:3])) # FALSE - OK

此外,如果您希望检查尽可能快,则应避免使用sapply并转而使用vapply

d <- data.frame(matrix(runif(1e6), nrow=10), letters[1:10])

# @joran's method
is.finite.data.frame <- function(obj){
    sapply(obj,FUN = function(x) all(is.finite(x)))
}

system.time( x <- is.finite(d) ) # 0.42 secs

# Using vapply instead...
is.finite.data.frame <- function(obj) {
    vapply(obj,FUN = function(x) all(is.finite(x)), logical(1))
}

system.time( y <- is.finite(d) ) # 0.20 secs

identical(x,y) # TRUE

答案 3 :(得分:3)

一个区别是is.nais.finite是不同类型的函数。 is.na是通用的,将根据参数的类进行调度。

> methods("is.na")
[1] is.na.data.frame      is.na.numeric_version is.na.POSIXlt        
[4] is.na.raster*        

   Non-visible functions are asterisked

特别注意有一个is.na.data.frame功能。看看那个功能:

> is.na.data.frame
function (x) 
{
    y <- do.call("cbind", lapply(x, "is.na"))
    if (.row_names_info(x) > 0L) 
        rownames(y) <- row.names(x)
    y
}
<bytecode: 00000000054F40F0>
<environment: namespace:base>

执行工作的部分是do.call("cbind", lapply(x, "is.na"))调用,它将列放在一起(cbind),这是lapply(x, "is.na")的结果。使用示例data.frame(mtcars)运行此代码:

> lapply(mtcars, "is.na")
$mpg
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

$cyl
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

$disp
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

$hp
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

$drat
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

$wt
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

$qsec
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

$vs
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

$am
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

$gear
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

$carb
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

我们发现这实际上只是一个逐列计算,并重新组合成一个data.frame。

将其与is.finite进行比较,后者没有data.frames的特定功能:

> methods("is.finite")
no methods were found

实际上,它是一种原始方法,意味着细节是C代码,而不是R代码。

> is.finite
function (x)  .Primitive("is.finite")

如果您想使用is.finite进行逐列计算,可以像is.na.data.frame一样进行包装。

> do.call(cbind, lapply(mtcars, is.finite))
       mpg  cyl disp   hp drat   wt qsec   vs   am gear carb
 [1,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [2,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [3,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [4,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [5,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [6,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [7,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [8,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [9,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[10,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[11,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[12,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[13,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[14,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[15,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[16,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[17,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[18,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[19,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[20,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[21,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[22,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[23,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[24,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[25,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[26,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[27,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[28,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[29,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[30,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[31,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[32,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE

后者也可以作为

获得
sapply(mtcars, is.finite)

不测试什么是最有效的。