2012-05-07 39 views
5

Tôi có một khung dữ liệu lớn về hồ sơ thăm khám bác sĩ. Tôi chỉ muốn chọn những hàng có ít nhất một trong 11 mã chẩn đoán được liệt kê trong một tập hợp mã chẩn đoán được chỉ định mà tôi quan tâm.R: Chọn các hàng từ một khung dữ liệu dựa trên một tập hợp các giá trị quan tâm xuất hiện trong các cột nhất định

Dataframe là 18 cột bởi 39,019 hàng. Tôi quan tâm đến các mã chẩn đoán trong cột 6:16. Đây là một mẫu dữ liệu cho các cột chẩn đoán 11 chỉ (để bảo vệ thông tin mang tính chất):

diag1 diag2 diag3 diag4 diag5 diag6 diag7 diag8 diag9 diag10 diag11 
786 272 401 782 250 91912 530 NA NA NA  NA 
845 530 338 311 NA NA NA  NA NA NA  NA 

Đây là mã tôi đã cố gắng sử dụng:

mydiag <- c(401, 410, 411, 413, 415:417, 420:429, 434, 435, 444, 445, 451, 460:466, 480:486, 490:493, 496, 786) 
y = apply(dt[,paste("diag", 1:11, sep="")], 1, function(x) sum((any(x !=NA %in% mydiag)))) 
y = as.data.frame(y) 

Như bạn có thể thấy, trong vòng 2 các hàng ví dụ mà tôi đã cung cấp, tôi muốn giữ hàng đầu tiên nhưng lại ném hàng thứ hai bởi vì nó không có bất kỳ mã nào tôi muốn. Mẫu mã mà tôi đã cung cấp không hoạt động - tôi nhận được một vectơ có giá trị 39,019 "1". Vì vậy, tôi đoán các tuyên bố áp dụng đang được đọc như một logic bằng cách nào đó, nhưng tôi biết thực tế là không phải tất cả các hàng có một mã quan tâm như vậy trong trường hợp đó tôi đã có thể mong đợi 1 và 0.

Có cách nào tốt hơn để thực hiện tác vụ chọn hàng này không?

Trả lời

5

Tôi nghĩ bạn đang làm quá nhiều thứ với bit !=NA trong đó. Vì NA không xuất hiện trong mydiag, bạn có thể thả hoàn toàn. Vì vậy, tuyên bố áp dụng của bạn sau đó có thể trở thành:

goodRows <- apply(dat, 1, function(x) any(x %in% mydiag)) 
dat[goodRows,] 
#--------------- 
    diag1 diag2 diag3 diag4 diag5 diag6 diag7 diag8 diag9 diag10 diag11 
1 786 272 401 782 250 91912 530 NA NA  NA  NA 
2

vấn đề này xuất phát từ chức năng của bạn function(x) sum((any(x !=NA %in% mydiag)))

x != NA có thể được xây dựng tốt hơn sử dụng !is.na(x) nhưng bạn phải thừa nhận rằng đây trả về một vector logic. Vì vậy, bạn đang lấy kết quả của một vector hợp lý và sau đó kiểm tra xem kết quả có trong mydiag hay không. Tôi đoán bạn chỉ muốn lấy các giá trị không phải là na và kiểm tra xem có bất kỳ giá trị nào trong mydiag hay không.

x[!is.na(x)] %in% mydiag 

sẽ hoạt động tốt hơn cho điều đó. Nhưng bạn thực sự thậm chí không cần phải kiểm tra NAS từ NA không có trong vector của bạn vì vậy bất kỳ phần tử trong x đó là NA sẽ trả về false cho x %in% mydiag

function(x){any(x %in% mydiag)} 

phải là một cách tốt đẹp để có được một kể giá trị logic bạn nếu hàng đáp ứng tiêu chí của bạn hay không.

# Get the row numbers of the rows you want 
id = apply(dt[,paste("diag", 1:11, sep="")], 1, function(x){any(x %in% mydiag)}) 
# Just grab those rows 
y <- dt[id, ] 
+0

Cảm ơn rất nhiều! Bạn nói đúng - và bây giờ tôi nhớ rằng tôi đã đi trước bản thân mình. Tôi đã muốn loại trừ các "NA" bởi vì tôi đã lấy số tiền mà tôi hoàn toàn quên mất khi tôi bắt đầu nhập câu hỏi này. Vì vậy, nếu sau đó tôi muốn tìm hiểu tổng số chẩn đoán được liệt kê cho mỗi hàng (trong ví dụ trên là 7 và 4), đây là lần thử đầu tiên của tôi: id2 = apply (y [, paste ("diag", 1:11, sep = "")], 1, hàm (x) tổng ({bất kỳ (x [! Is.na (x)])})) – mEvans

+0

'tổng hợp' có đối số na.rm sẽ cho phép bạn bỏ qua tất cả điều này. Ngoài ra ... nó là nver trường hợp mà bất cứ điều gì "== NA" và ngược lại không bao giờ là trường hợp mà bất cứ điều gì "! = NA". Kết quả sẽ luôn là ... NA. Vì vậy, có lẽ ... 'id2 = áp dụng (y [, dán (" diag ", 1:11, sep =" ")], 1, hàm (x) {sum (bất kỳ (x), na.rm = TRUE) })) ' –

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