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