2014-11-11 24 views
14

Có thể select trong dplyr được sử dụng với vectơ lôgic không?dplyr chọn sử dụng lôgic

dat <- tbl_df(mtcars) 
isNum <- sapply(dat, is.numeric) 
select(dat, isNum) 
select(dat, isNum) 

Lỗi trong tên (sel) [giấu tên] < - sel [giấu tên]: NA không được phép vào tập subscripted

Chỉ số hoạt động select(dat,(1:ncol(dat))[isNum]) vậy tại sao không phải là một logic ?

Sửa 1:

Khi tôi thấy chức năng helper cho chọn như starts_with select(dat,starts_with("m")) tôi cho rằng họ sẽ làm việc với một logic

Chỉnh sửa 2:

select(dat, which(isNum)) làm việc

+2

Có thể là một chủ đề cho 'dplyr 0.3.1'] (https://github.com/hadley/dplyr/issues/497): "Nói chung, cách tốt nhất để lọc cột bằng một số điều kiện boolean trong' dplyr' là gì? " – Henrik

+1

Tôi nghĩ bạn nên đăng 'chọn (dat, which (isNum))' làm câu trả lời (và thậm chí chấp nhận nó nếu nó có vẻ là giải pháp tốt nhất) –

Trả lời

10

Câu trả lời của tôi sẽ là:

  • không ("Có thể chọn trong dplyr được sử dụng với một vector logic?")

bằng chứng: (1) ví dụ của bạn, (2) các trang trợ giúp:

. ..: Danh sách các biểu thức không được trích dẫn bằng dấu phẩy được phân cách bằng dấu phẩy. Bạn có thể xử lý các tên biến số giống như chúng là các vị trí. Sử dụng các giá trị dương để chọn biến; sử dụng giá trị âm để thả biến.

Không nói gì về vectơ hợp lý. Lấy làm tiếc.

  • Tôi không biết ("tại sao không logic?") Bạn có thể đặt trong một yêu cầu tính năng ...

Đó là một chút phiền phức, nhưng

select_(dat,.dots=names(isNum)[isNum]) 

công trình (lưu ý rằng bạn cần có biến thể select_ cho phép sử dụng một vector ký tự). Tuy nhiên, các kiểu máy ảnh cũ

subset(dat,select=isNum) 

có vẻ hoạt động tốt (trừ khi không chơi độc đáo với dplyr theo cách khác mà tôi chưa từng nghĩ đến).

Nếu bạn nhìn vào mã của dplyr:::starts_with, bạn có thể thấy rằng nó trả về một vector của các vị trí, không phải là một vector logic

function (vars, match, ignore.case = TRUE) 
{ 
    stopifnot(is.string(match), !is.na(match), nchar(match) > 
     0) 
    if (ignore.case) 
     match <- tolower(match) 
    n <- nchar(match) 
    if (ignore.case) 
     vars <- tolower(vars) 
    which(substr(vars, 1, n) == match) 
} 

tôi sẽ đề nghị bạn nên cố gắng sửa đổi chức năng này để tạo ra một is_numeric tương đương, nhưng tôi không hiểu phép thuật cơ bản đủ tốt ...

16

Như Ben gợi ý:

select(dat, which(isNum))

+0

Điều này thực sự hữu ích vì chúng ta có thể đặt 'cái nào' trước bất kỳ xây dựng logic để trả về số cột. –

2

Như đã trình bày rất rõ trong câu trả lời khác, câu trả lời cho câu hỏi cụ thể của bạn là không. Bạn không thể sử dụng vectơ lôgic trong dplyr::select().

Tuy nhiên, trong các phiên bản mới hơn của dplyr (v> = 0.5.0) có chức năng mới hỗ trợ sử dụng chức năng vị ngữ được áp dụng cho các cột hoặc vector lôgic: select_if().

Sử dụng select_if với một chức năng ngữ, ví dụ bạn có thể được đơn giản hóa như sau:

tbl_df(mtcars) %>% dplyr::select_if(is.numeric) 

Tuy nhiên, bạn cũng có thể sử dụng select_if với một vector logic. Điều này trực tiếp đề cập đến trường hợp sử dụng của bạn ở trên, trông giống như sau:

dat <- tbl_df(mtcars) 
isNum <- sapply(dat, is.numeric) 
select_if(dat, isNum) 
Các vấn đề liên quan