2013-05-24 81 views
7

Tôi mới trên R và tôi có một data.frame, được gọi là "CT", có chứa một cột có tên là "ID" có chứa hàng trăm số nhận dạng khác nhau (đây là những bệnh nhân). Hầu hết các số xuất hiện một lần, nhưng một số khác xuất hiện hai hoặc ba lần (do đó, ở các hàng khác nhau). Trong data.frame CT, tôi muốn chèn một biến mới, được gọi là "countID", sẽ cho biết số lần xuất hiện của những bệnh nhân cụ thể này (nhiều bản ghi vẫn xuất hiện nhiều lần). Tôi đã thử hai chiến lược khác nhau sau khi đọc diễn đàn này: 1 chiến lược:đếm số lần xuất hiện trong cột và tạo biến trong R

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

Nhưng công việc doesnt này, tôi nhận được chỉ có một số. chiến lược thứ 2: tạo ra một khung dữ liệu với hai cột (một là ID, một là đếm) và trận đấu dataframe này với 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 

Vì vậy, đây hoạt động tốt nhưng tôi không thể làm tan chảy hai data.frames: các số hàng không khớp giữa "out" và "CT" (trong số đó có ít hàng hơn). Có thể ai đó có giải pháp thanh lịch để thêm số lần xuất hiện trực tiếp vào CT dữ liệu, hoặc khớp chính xác với hai data.frames? Cảm ơn trước, Denis

+0

+1 cho cho thấy đầu vào và đầu ra mong đợi, nhưng tiếp theo thời gian bạn đăng, tạo ví dụ của bạn [** reproducible **] (http://stackoverflow.com/q/5963269/1478381) bằng cách bao gồm một số dữ liệu. chào mừng bạn đến với SO! –

Trả lời

5

Bạn gần như có! rle sẽ làm việc rất độc đáo, bạn chỉ cần để sắp xếp bảng của bạn trên ID trước khi tính toán 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

Cảm ơn bạn rất nhiều, điều này hoạt động tốt! - Tôi sẽ cố gắng cải thiện việc chỉnh sửa và bao gồm một số dữ liệu ví dụ vào lần sau. Tuyệt quá! – den

+2

Ngoài ra 'biến đổi (CT, Đếm = ave (id, id, FUN = chiều dài))' –

2

Nếu bạn không cảm thấy nhu cầu sử dụng cơ sở R, plyr làm nhiệm vụ này dễ dàng:

> 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

Cảm ơn bạn rất nhiều, tôi cũng sẽ thử điều này. – den

3

data.table thường cung cấp cách nhanh nhất

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 
Các vấn đề liên quan