2013-05-24 12 views
7

Jestem nowy na R i mam data.frame, zwany "CT", zawierający kolumnę o nazwie "ID" zawierającą kilkaset różnych numerów identyfikacyjnych (są to pacjenci). Większość liczb pojawia się raz, ale niektóre pojawiają się dwa lub trzy razy (a więc w różnych wierszach). W CT data.frame chciałbym wstawić nową zmienną, o nazwie "countID", która wskazywałaby na liczbę wystąpień tych konkretnych pacjentów (wiele zapisów powinno wciąż pojawiać się kilka razy). Próbowałem dwa różne strategie po przeczytaniu tego forum: 1-ta strategia:liczenie wystąpień w kolumnie i tworzenie zmiennej w R

CT <- cbind(CT, countID=sequence(rle(CT.long$ID)$lengths) 

Ale ta praca nie robi, ja się tylko jeden licznik. 2-te strategia: utworzyć ramkę danych z dwóch kolumnach (jeden jest identyfikator, jeden licznik) i mecz ten dataframe z CT:

tabs <- table(CT.long$ID) 
out <- data.frame(item=names(unlist(tabs)),count=unlist(tabs)[],stringsAsFactors=FALSE) 
rownames(out) = c() 
head(out) 

# item count 
# 1 1.312  1 
# 2 1.313  2 
# 3 1.316  1 
# 4 1.317  1 
# 5 1.321  1 
# 6 1.322  1 

Tak to działa dobrze, ale nie mogę się topić dwa data.frames: the liczba wierszy nie pasuje pomiędzy "out" i "CT" (obecnie ma mniej rzędów oczywiście). Być może ktoś ma eleganckie rozwiązanie do dodawania liczby wystąpień bezpośrednio w CT danych, lub poprawnie dopasować dwa dane.frames? Dzięki z góry, Denis

+0

+1 do do pokazywania wejście i wyjście oczekiwany, ale następnym czas, jaki publikujesz, spraw, by twój przykład [** odtwarzalny **] (http://stackoverflow.com/q/5963269/1478381) zawierał niektóre dane. witamy w SO! –

Odpowiedz

5

Byłaś prawie tam! rle będzie działać bardzo dobrze, po prostu trzeba posortować tabelę na ID przed obliczaniem rle:

CT <- data.frame(value = runif(10) , id = sample(5,10,repl=T)) 

# sort on ID when calculating rle 
Count <- rle(sort(CT$id)) 

# match values 
CT$Count <- Count[[1]][ match(CT$id , Count[[2]]) ] 
CT 
#  value id Count 
#1 0.94282600 1  4 
#2 0.12170165 2  2 
#3 0.04143461 1  4 
#4 0.76334609 3  2 
#5 0.87320740 4  1 
#6 0.89766749 1  4 
#7 0.16539820 1  4 
#8 0.98521044 5  1 
#9 0.70609853 3  2 
#10 0.75134208 2  2 
+1

Dziękuję bardzo, to działa dobrze! - Postaram się poprawić edycję i dołączyć kilka przykładowych danych następnym razem. Wspaniały! – den

+2

Również 'transform (CT, Count = ave (id, id, FUN = długość))' –

2

Jeśli nie czujesz potrzebę stosowania zasady R, plyr czyni to zadanie łatwe:

> set.seed(3) 
> library(plyr) 
> ct <- data.frame(id=sample(1:10,15,replace=TRUE),item=round(rnorm(15),3)) 
> ct <- ddply(ct,.(id),transform,idcount=length(id)) 
> head(ct) 
    id item idcount 
1 2 0.953  2 
2 2 1.342  2 
3 3 0.693  1 
4 4 -0.584  2 
5 4 -2.161  2 
6 6 -0.323  5 
+0

Dziękuję bardzo, spróbuję tego również. – den

3

data.table zwykle zapewnia najszybszy sposób

set.seed(3) 
library(data.table) 
ct <- data.table(id=sample(1:10,15,replace=TRUE),item=round(rnorm(15),3)) 
st <- ct[,countid:=.N,by=id] 
id item countid 
1: 2 0.953  2 
2: 9 0.535  2 
3: 4 -0.584  2 
4: 4 -2.161  2 
5: 7 -1.320  3 
6: 7 0.810  3 
7: 2 1.342  2 
8: 3 0.693  1 
9: 6 -0.323  5 
10: 7 -0.117  3 
11: 6 -0.423  5 
12: 6 -0.835  5 
13: 6 -0.815  5 
14: 6 0.794  5 
15: 9 0.178  2 
Powiązane problemy