2011-11-17 40 views
15

Tôi muốn kiểm tra xem một data.frame có bất kỳ phần tử không hữu hạn nào không.Làm thế nào để kiểm tra một data.frame cho bất kỳ phi hữu hạn

Điều này dường như đánh giá từng cột, trở về FALSE cho mỗi (Tôi đoán đánh giá của các data.frame như một danh sách):

any(!is.finite(x)) 

Tôi không hiểu tại sao điều này sẽ khác với ở trên , nhưng nó hoạt động tốt nếu chỉ kiểm tra cho NA:

any(!is.na(x)) 

Tôi muốn giải pháp hiệu quả nhất có thể. Tôi nhận ra tôi chỉ có thể làm ...

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

Hiệu quả là tốt, nhưng ... bạn có bất kỳ bằng chứng nào về tốc độ của thử nghiệm này (hoặc sẽ là) một nút cổ chai trong phân tích của bạn không? –

+2

Nó không phải là một nút cổ chai. Tôi thấy câu hỏi này là một cơ hội để tìm hiểu thêm về R. Tôi tự hỏi nếu tôi thiếu một số kỹ thuật để đánh giá các phần tử trong một data.frame khác với kỹ thuật rõ ràng chuyển đổi sang một kiểu dữ liệu khác – SFun28

Trả lời

15

Nếu bạn gõ methods(is.na) bạn sẽ thấy rằng nó có một phương pháp data.frame, mà có lẽ giải thích lý do tại sao nó hoạt động theo cách bạn mong đợi, nơi is.finite không. Các giải pháp thông thường sẽ được viết một mình, vì nó chỉ có một dòng. Một cái gì đó giống như có lẽ đây,

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

Cảm ơn trỏ đến phương thức() cũng như giải pháp! Tôi sẽ sử dụng "tất cả" thay vì "bất kỳ" và xác định một cột data.frame hữu hạn như một cột chỉ với các số hữu hạn – SFun28

+0

@ SFun28 Điểm tốt, cảm ơn. Đánh máy hơi nhanh. Chỉnh sửa để phản ánh quan điểm của bạn. – joran

6

Tôi giả định lỗi mà bạn đang nhận được như sau:

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

Lỗi này là do is.infinite()is.finite() chức năng này không được thực hiện với một phương pháp cho dữ liệu .frames. Hàm is.na() không có phương thức data.frame.

Cách khắc phục sự cố này là apply() chức năng cho mọi hàng, cột hoặc phần tử trong data.frame. Dưới đây là một ví dụ sử dụng sapply() để áp dụng các is.infinite() chức năng cho mỗi phần tử:

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

Một khác biệt là is.nais.finite nhiều loại khác nhau của các chức năng. is.na là một chung chung và sẽ gửi dựa trên lớp của đối số.

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

    Non-visible functions are asterisked 

Lưu ý đặc biệt rằng có chức năng is.na.data.frame. Nhìn vào hàm:

> 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> 

phần mà làm việc là cuộc gọi do.call("cbind", lapply(x, "is.na")) trong đó đặt các cột với nhau (cbind) mà là kết quả của lapply(x, "is.na"). Chỉ chạy điều này với một ví dụ 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 

chúng ta thấy rằng đây thực sự chỉ là tính toán theo cột, được đặt lại với nhau thành một data.frame.

Hãy so sánh đó để is.finite mà không có một chức năng cụ thể cho data.frames:

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

Trong thực tế, nó là một phương pháp nguyên thủy, có nghĩa là chi tiết có trong mã C, không R mã.

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

Nếu bạn muốn làm một phép tính cột-khôn ngoan với is.finite, bạn có thể quấn nó như is.na.data.frame làm.

> 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 

này sau này cũng có thể được nhận như

sapply(mtcars, is.finite) 

Không thử nghiệm trên những gì sẽ là hiệu quả nhất, mặc dù.

+0

cảm ơn, Brian! Tôi đánh giá cao sự cố của is.na.data.frame – SFun28

4

Giải pháp gọi as.matrix của bạn sẽ chỉ hoạt động nếu data.frame chỉ có các cột số. Nếu không, ma trận thường sẽ trở thành ma trận ký tự và kết quả sẽ sai ở mọi nơi ...

@joran có cách tiếp cận tốt, nhưng bạn sẽ gặp vấn đề với cột yếu tố trừ khi thêm phương pháp cho các yếu tố quá v.v. ..

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 

Ngoài ra, nếu bạn muốn kiểm tra để chạy càng nhanh càng tốt, bạn nên tránh sapply và đi cho vapply để thay thế.

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 
+0

Những điểm tuyệt vời về as.matrix, cột yếu tố và vapply! Câu trả lời này chứa đầy những thứ tốt. =) – SFun28

Các vấn đề liên quan