2012-05-07 13 views
5

Mam dużą ramkę danych z zapisów wizyt lekarskich. Chcę wybrać tylko te wiersze, w których co najmniej jeden z 11 wymienionych kodów diagnostycznych znajduje się w określonym zbiorze kodów diagnostycznych, które mnie interesują.R: Wybieranie wierszy z ramki danych na podstawie zestawu wartości pojawiających się w niektórych kolumnach

Ramka danych ma 18 kolumn po 39 019 rzędach. Interesują mnie kody diagnostyczne w kolumnach 6:16. Oto przykładowe dane dla tych 11 kolumn diagnozy tylko (w celu ochrony zidentyfikowania informacji):

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 

Oto kod próbowałem użyć:

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) 

Jak widać, w 2 przykładowe wiersze pod warunkiem, chciałbym zachować pierwszy wiersz, ale wyrzucić drugi wiersz, ponieważ nie ma żadnego z kodów, które chcę. Podany kod przykładowy nie działa - otrzymuję wektor o wartości 39 019 "1". Zgaduję więc, że instrukcja apply jest odczytywana jakoś logicznie, a jednak wiem, że nie wszystkie wiersze mają kod zainteresowania, więc w tym przypadku oczekiwałbym 1 i 0.

Czy istnieje lepszy sposób na wykonanie tego zadania wyboru wiersza?

Odpowiedz

5

Chyba jesteś overcomplicating rzeczy z !=NA bitu tam. Ponieważ NA nie pojawia się w mydiag, możesz ją całkowicie upuścić. Twoje oświadczenie może stać się:

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

Problem zaczyna się od swojej funkcji function(x) sum((any(x !=NA %in% mydiag)))

x != NA mogłoby być lepiej skonstruowany przy użyciu !is.na(x) ale trzeba przyznać, że ten zwraca logiczną wektor. Więc bierzesz wynik logicznego wektora, a następnie sprawdzasz, czy wynik jest w mydiag. Zgaduję, że chcesz tylko wziąć wartości, które nie są na i sprawdzić, czy którekolwiek z nich są w mydiag.

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

będzie działać o wiele lepiej. Ale naprawdę nie trzeba nawet sprawdzić NAS NA ponieważ nie jest w wektorze więc każdy element x czyli NA zwróci false dla x %in% mydiag

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

Jest to dobry sposób, aby uzyskać wartość logiczną opowiadanie jeśli rząd spełnia twoje kryteria, czy nie.

# 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

Dziękuję bardzo! Masz rację - a teraz pamiętam, że wyprzedzałem siebie. Chciałem wykluczyć "NA", ponieważ brałem sumę - o czym całkowicie zapomniałem, kiedy zacząłem pisać to pytanie. Tak więc, gdybym wtedy chciał dowiedzieć się, ile wszystkich diagnoz zostało wymienionych dla każdego wiersza (w powyższym przykładzie, który byłby 7 i 4), jest to moja pierwsza próba: id2 = zastosuj (y [, wklej ("diag", 1:11, sep = "")], 1, funkcja (x) sum ({any (x [! Is.na (x)])})) – mEvans

+0

'sum' ma argument na.rm, który pozwoliłby pomijasz to wszystko. Również ... w każdym przypadku jest tak, że cokolwiek "== NA" i odwrotnie nigdy nie jest tak, że cokolwiek "! = NA". Wynik zawsze będzie ... NA. Może więc ... 'id2 = apply (y [, paste (" diag ", 1:11, sep =" ")], 1, funkcja (x) {suma (dowolna (x), na.rm = TRUE) })) ' –

Powiązane problemy