Как проверить data.frame для любых не конечных
Я хочу проверить, имеет ли файл data.frame какие-либо не конечные элементы.
Кажется, что оценивается каждый столбец, возвращая FALSE для каждого (я предполагаю, что он оценивает data.frame как список):
any( !is.finite( x ) )
Я не понимаю, почему это ведет себя иначе, чем указано выше, но отлично работает, если просто проверять NA:
any( !is.na( x ) )
Я хочу, чтобы решение было максимально эффективным. Я понимаю, что могу просто сделать...
any( !is.finite( as.matrix( x ) ) )
Ответы
Ответ 1
Если вы наберете methods(is.na)
, вы увидите, что у него есть метод data.frame
, который, вероятно, объясняет, почему он работает так, как вы ожидаете, где is.finite
нет. Обычным решением было бы написать один, поскольку это только одна строка. Что-то вроде этого возможно,
is.finite.data.frame <- function(obj){
sapply(obj,FUN = function(x) all(is.finite(x)))
}
Ответ 2
Я предполагаю, что ошибка, которую вы получаете, следующая:
> 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) )
Ответ 3
Ваше решение вызова 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 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
Ответ 4
Одно отличие состоит в том, что is.na
и is.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)
Нет тестирования на то, что было бы наиболее эффективным.