2014-10-04 15 views
5

Tôi có một khung dữ liệu hiện có lớn hơn nhiều. Đối với ví dụ nhỏ hơn này tôi muốn thay thế một số biến (thay thế trạng thái (df1)) bằng newstate (df2) theo cột "đầu tiên". Vấn đề của tôi là các giá trị được trả về là NA vì chỉ một số tên được khớp trong dataframe mới (df2).Có giá trị trả về danh nghĩa khi đang sử dụng chức năng đối sánh trong R

hiện dataframe:

state = c("CA","WA","OR","AZ") 
first = c("Jim","Mick","Paul","Ron") 
df1 <- data.frame(first, state) 

     first state 
    1 Jim CA 
    2 Mick WA 
    3 Paul OR 
    4 Ron AZ 

New dataframe để phù hợp với dataframe hiện

state = c("CA","WA") 
newstate = c("TX", "LA") 
first =c("Jim","Mick") 
df2 <- data.frame(first, state, newstate) 

    first state newstate 
1 Jim CA  TX 
2 Mick WA  LA 

Cố gắng sử dụng trận đấu nhưng trả NA cho "nhà nước", nơi một phù hợp với "đầu tiên" biến từ df2 không phải là được tìm thấy trong khung dữ liệu gốc.

df1$state <- df2$newstate[match(df1$first, df2$first)] 

    first state 
1 Jim TX 
2 Mick LA 
3 Paul <NA> 
4 Ron <NA> 

Có cách nào bỏ qua nomatch hoặc có nomatch trả về biến hiện tại không? Đây sẽ là ví dụ về kết quả mong muốn: Trạng thái của Jim/Mick được cập nhật trong khi trạng thái của Paul và Ron không thay đổi.

 first state 
    1 Jim TX 
    2 Mick LA 
    3 Paul OR 
    4 Ron AZ 

Trả lời

6

Đây có phải là những gì bạn muốn; BTW trừ khi bạn thực sự muốn làm việc với các yếu tố, sử dụng stringsAsFactors = FALSE trong cuộc gọi data.frame của bạn. Chú ý việc sử dụng nomatch = 0 trong cuộc gọi trùng khớp.

> state = c("CA","WA","OR","AZ") 
> first = c("Jim","Mick","Paul","Ron") 
> df1 <- data.frame(first, state, stringsAsFactors = FALSE) 
> state = c("CA","WA") 
> newstate = c("TX", "LA") 
> first =c("Jim","Mick") 
> df2 <- data.frame(first, state, newstate, stringsAsFactors = FALSE) 
> df1 
    first state 
1 Jim CA 
2 Mick WA 
3 Paul OR 
4 Ron AZ 
> df2 
    first state newstate 
1 Jim CA  TX 
2 Mick WA  LA 
> 
> # create an index for the matches 
> indx <- match(df1$first, df2$first, nomatch = 0) 
> df1$state[indx != 0] <- df2$newstate[indx] 
> df1 
    first state 
1 Jim TX 
2 Mick LA 
3 Paul OR 
4 Ron AZ 
+0

Mã của bạn hoạt động. [Cảm ơn bạn.] Nhưng bạn có thể giải thích tại sao bạn có' indx! = 0' ở bên trái của dấu bằng và 'indx' trên phía bên phải của bằng? 'df1 $ state [indx! = 0] <- df2 $ newstate [indx]' –

2
library(data.table) 
DT1 <- as.data.table(df1) 
DT2 <- as.data.table(df2) 


setkey(DT1, first, state) 
setkey(DT2, first, state) 

DT1[DT2] 
# first state newstate 
# 1: Jim CA  TX 
# 2: Mick WA  LA 

Lưu ý rằng [.data.table cũng có một nomatch đối số, ví dụ:

DT2[DT1, nomatch=0] 
# first state newstate 
# 1: Jim CA  TX 
# 2: Mick WA  LA 

DT2[DT1, nomatch=NA] 
# first state newstate 
# 1: Jim CA  TX 
# 2: Mick WA  LA 
# 3: Paul OR  NA 
# 4: Ron AZ  NA 

3

Tôi nghĩ rằng bạn sẽ nhận được hành vi tốt hơn với vectơ nhân vật hơn với các yếu tố.

> df1 <- data.frame(first, state,stringsAsFactors=FALSE) 
> state = c("CA","WA") 
> newstate = c("TX", "LA") 
> first =c("Jim","Mick") 
> df2 <- data.frame(first, state, newstate, stringsAsFactors=FALSE) 
> df1[ match(df2$first, df1$first), "state"] <- df2$newstate 
> df1 
    first state 
1 Jim TX 
2 Mick LA 
3 Paul OR 
4 Ron AZ 
+0

Tôi đã có thể tạo lại câu trả lời của bạn. Sau đó tôi chuyển đổi dữ liệu ban đầu của mình, tất cả thành ký tự và định dạng được kiểm tra bằng str(). Chúng có vẻ giống hệt nhau về cấu trúc. Khi tôi thử tôi thử nó trên tập dữ liệu lớn hơn, ban đầu của tôi, tôi nhận được: "Lỗi trong' [<-. Data.frame' ('* tmp *', match (df2 $ first, df1 $ first), : giá trị bị thiếu không được phép trong phân bổ chỉ số của khung dữ liệu " – panstotts

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