2012-03-24 32 views

Trả lời

16

Xem chức năng all()any() cho các bộ phận đầu tiên và thứ hai của câu hỏi của bạn tương ứng. Có thể sử dụng chức năng apply() để chạy các hàm trên hàng hoặc cột. (MARGIN = 1 là các hàng, MARGIN = 2 là các cột, v.v ...). Lưu ý tôi sử dụng apply() trên df[, -1] để bỏ qua biến số id khi thực hiện so sánh.

Phần 1:

> df <- data.frame(id=c(1:5), v1=c(0,15,9,12,7), v2=c(9,32,6,17,11)) 
> df[apply(df[, -1], MARGIN = 1, function(x) all(x > 10)), ] 
    id v1 v2 
2 2 15 32 
4 4 12 17 

Phần 2:

> df[apply(df[, -1], MARGIN = 1, function(x) any(x > 10)), ] 
    id v1 v2 
2 2 15 32 
4 4 12 17 
5 5 7 11 

Để xem những gì đang xảy ra, x > 10 trả về một vector logic cho mỗi hàng (thông qua apply() cho biết mỗi phần tử là lớn hơn 10 . all() trả về TRUE nếu tất cả các yếu tố của vé vào là TRUEFALSE nếu không.trả lại TRUE nếu bất kỳ của các yếu tố trong đầu vào là TRUEFALSE nếu tất cả là FALSE.

sau đó tôi sử dụng vector logic phát sinh từ việc apply() gọi

> apply(df[, -1], MARGIN = 1, function(x) all(x > 10)) 
[1] FALSE TRUE FALSE TRUE FALSE 
> apply(df[, -1], MARGIN = 1, function(x) any(x > 10)) 
[1] FALSE TRUE FALSE TRUE TRUE 

để tập hợp con df (như hình trên).

5

Điều này có thể được thực hiện bằng cách sử dụng apply với lề 1, sẽ áp dụng cho mỗi hàng. Các chức năng để kiểm tra một hàng nhất định sẽ được

function(row) {all(row > 10)} 

Vì vậy, con đường để trích xuất các hàng mình là

df[apply(df, 1, function(row) {all(row > 10)}),] 
+0

+1 - và thay thế 'tất cả' bằng' bất kỳ' cho câu hỏi thứ hai. – flodel

+2

chờ, bạn muốn làm 'tất cả (hàng [-1]> 10)' không tính đến cột 'id'. Hoặc áp dụng hàm trên 'df [-1]'. – flodel

0

Một tùy chọn lặp lại từng hàng (ví dụ: apply) và sử dụng any hoặc all, như được đề xuất trong hai câu trả lời còn lại. Tuy nhiên, điều này có thể không hiệu quả đối với các khung dữ liệu lớn.

Cách tiếp cận được vector hóa sẽ sử dụng rowSums để xác định số lượng giá trị trong mỗi hàng khớp với tiêu chí của bạn và lọc dựa trên tiêu chí đó.

Khi lọc để hàng nơi mọi thứ đều ít nhất 10, điều này cũng giống như lọc đối với trường hợp số lượng các giá trị không quá 10 là 0:

df[rowSums(df[,-1] <= 10) == 0,] 
# id v1 v2 
# 2 2 15 32 
# 4 4 12 17 

Tương tự, rowSums có thể dễ dàng được sử dụng để tính toán các hàng với bất cứ điều gì vượt quá 10:

df[rowSums(df[,-1] > 10) > 0,] 
# id v1 v2 
# 2 2 15 32 
# 4 4 12 17 
# 5 5 7 11 

việc tăng tốc là rõ ràng với một đầu vào lớn hơn:

set.seed(144) 
df <- matrix(sample(c(1, 10, 20), 3e6, replace=TRUE), ncol=3) 
system.time(df[apply(df[, -1], MARGIN = 1, function(x) all(x > 10)), ]) 
# user system elapsed 
# 1.754 0.156 2.102 
system.time(df[rowSums(df[,-1] <= 10) == 0,]) 
# user system elapsed 
# 0.04 0.01 0.05 
Các vấn đề liên quan