2013-02-25 61 views
9

Trong ví dụ dưới đây, userids là khung dữ liệu tham chiếu của tôi và userdata là khung dữ liệu nơi thay thế sẽ diễn ra.Thay thế giá trị trong khung dữ liệu dựa trên khung dữ liệu khác trong R

> userids <- data.frame(USER=c('Ann','Jim','Lee','Bob'),ID=c(1,2,3,4)) 
> userids 
    USER ID 
1 Ann 1 
2 Jim 2 
3 Lee 3 
4 Bob 4 

> userdata <- data.frame(INFO=c('foo','bar','foo','bar'), ID=c('Bob','Jim','Ann','Lee'),AGE=c('43','33','53','26'), FRIENDID=c('Ann',NA,'Lee','Jim')) 
> userdata 
    INFO ID AGE FRIENDID 
1 foo Bob 43  Ann 
2 bar Jim 33  NA 
3 foo Ann 53  Lee 
4 bar Lee 26  Jim 

Làm thế nào để thay thế ID và FRIENDID trong userdata với ID tương ứng với USER trong userids?

Kết quả mong muốn:

INFO ID AGE FRIENDID 
1 foo 4 43  1 
2 bar 2 33  NA 
3 foo 1 53  3 
4 bar 3 26  2 
+0

Ý của bạn là "đúng"? Bạn có muốn khớp 'userids $ USER' với' userdata $ ID' không? –

+1

Tôi đoán 'đúng' sẽ là' tương ứng'. – Arun

+0

@Robert, nó sẽ giúp có đầu ra mong muốn (để tránh những nhầm lẫn này, trong thời gian tới). – Arun

Trả lời

16

Sử dụng match:

userdata$ID <- userids$ID[match(userdata$ID, userids$USER)] 
userdata$FRIENDID <- userids$ID[match(userdata$FRIENDID, userids$USER)] 
0

Dưới đây là một thử sử dụng sqldf để có được kết quả như một bội số tham gia trên các cột differents.

library(sqldf) 
    sqldf('SELECT d.INFO,d.AGE,i1.ID ,i2.ID FRIENDID 
     FROM 
     userdata d 
     INNER JOIN 
     userids i1 ON (i1.USER=d.FRIENDID) 
     INNER JOIN 
     userids i2 ON (i2.USER=d.ID)') 

INFO AGE ID FRIENDID 
1 foo 43 1  4 
2 foo 53 3  1 
3 bar 26 2  3 

Nhưng điều này sẽ loại bỏ NA dòng! có lẽ ai đó có thể gợi ý cho tôi điều gì đó về cách đối phó với NA!

EDIT

Nhờ G. Grothendieck bình luận, thay thế INNER bởi LEFT chúng tôi nhận được kết quả.

sqldf('SELECT d.INFO,d.AGE,i1.ID ,i2.ID FRIENDID 
     FROM 
     userdata d 
     LEFT JOIN 
     userids i1 ON (i1.USER=d.FRIENDID) 
     LEFT JOIN 
     userids i2 ON (i2.USER=d.ID)') 
INFO AGE ID FRIENDID 
1 foo 43 1  4 
2 bar 33 NA  2 
3 foo 53 3  1 
4 bar 26 2  3 
+0

Về câu hỏi của bạn, hãy thay thế hai trường hợp 'INNER' bằng' LEFT'. –

1

Đây là một khả năng:

library(qdap) 
userdata$FRIENDID <- lookup(userdata$FRIENDID, userids) 
userdata$ID <- lookup(userdata$ID, userids) 

hay để giành chiến thắng giải thưởng một dòng:

userdata[, c(2, 4)] <- lapply(userdata[, c(2, 4)], lookup, key.match=userids) 
+0

'qdap' trông khá tuyệt, nhưng tôi không thấy nó trong kho của tôi. – N8TRO

+1

Không chắc chắn lý do. Có lẽ đó là vì nó là một phiên bản mới hơn. Hãy thử 'install.packages (" qdap ")' hoặc bạn có thể sử dụng: 'library (devtools)' 'install_github (" qdap "," trinker ")' cho devel. phiên bản. –

+0

Không thành công. 'ERROR: dependency 'openNLP' không có sẵn cho gói 'qdap'' – N8TRO

0

Dưới đây là một giải pháp khả thi, mà cũng sẽ làm việc trên tập hợp dữ liệu với nhiều bản ghi của mỗi ID, mặc dù chúng tôi sẽ cần phải ép buộc biến ID và FRIENDID thành ký tự đầu tiên:

> userdata$ID <- sapply(userdata$ID, function(x){gsub(x, userids[userids$USER==x, 2], x)}) 
> userdata$FRIENDID <- sapply(userdata$FRIENDID, function(x){gsub(x, userids[userids$USER==x, 2], x)}) 
Các vấn đề liên quan