2016-12-11 2 views
0

Я новичок в R и у меня есть 2 кадра данных, как следующее:Сравнение двух кадров данных в R

df1 
T_id U_id U_code score 
A_0_1 UHJKI XPOS_hp 134 
B_1_3 NBVFR LKJ_mm 543 
C_9_0 TRFDA NBV_lp 80 
D_9_1 KOIUA TRE_po 212 
E_0_1 SDFRQ QAS_np 300 
E_0_1 SDKIJ JIT_mx 160 
F_0_1 JKOPA TOZ_po 79 

df2 
T_id U_id U_code score 
A_0_1 UHJKI XPOS_hp 150 
B_1_3 NBVFR LKJ_mm 520 
C_9_0 TRFDG NBJ_po 90 
D_9_1 KOIUA TRE_po 250 
E_0_1 SDFRQ QAS_np 300 
E_0_1 SDKIJ JIT_mx 160 
F_0_1 LOLPO JUZ_ic 90 

Я хотел бы сравнить оценку df1 и df2 для этих записей в df1, который имеет точно же T_id, U_id and U_code в df2 и классифицировать их на 3 группы в зависимости от условий (df1$score >df2$score, df1$score=df2$score, df$1score<df2score), как следующее:

df$1score=df2$score 
E_0_1 SDFRQ QAS_np 300 
E_0_1 SDKIJ JIT_mx 160 
df1$score > df2$score 
B_1_3 NBVFR LKJ_mm 543 
df1$score < df2$score 
A_0_1 UHJKI XPOS_hp 150 
D_9_1 KOIUA TRE_po 250 

Кроме того, я хотел бы хранить записи о df1, для которых не найдено в df2

No matches 
C_9_0 TRFDA NBV_lp 80 
F_0_1 JKOPA TOZ_po 79 

Я попытался следующий код R

comparison=function(df1,df2) 
{ 
df1_equal_df2=NULL 
df1_greater_than_df2=NULL 
df1_smaller_than_df2=NULL 
no_match=NULL 
if(df$T_id==df2$T_id && df1$U_id == df2$U_id && df1$U_code==df2$U_code && df1$score > df2$score) 
{ 
    df1_greater_than_df2=df$T_id 
} 
else if(df$T_id==df2$T_id && df1$U_id == df2$U_id && df1$U_code==df2$U_code && df1$score < df2$score) 
{ 
    df1_smaller_than_df2=df1$id 
} 
else if(df$T_id==df2$T_id && df1$U_id == df2$U_id && df1$U_code==df2$U_code && df1$score = df2$score) 
    { 
    df1_equal_df2=df$1 
    } 
else 
    { 
    no_match=df$1 
    } 

} 

но выше не работало. Как я могу получить желаемый результат. Просьба направлять меня

+2

Почему бы не объединить свои данные в первую очередь? Тогда все остальные операции легки. – Heroka

ответ

3

Мы можем сделать это с помощью dplyr:

library(dplyr) 
res <- df1 %>% left_join(df2, by=c("T_id","U_id","U_code")) %>% 
       mutate(comp=ifelse(score.x > score.y,"df1$score > df2$score",ifelse(score.x < score.y,"df1$score < df2$score","df1$score == df2$score"))) %>% 
       rename(score=score.x) %>% select(-score.y) 
## T_id U_id U_code score     comp 
##1 A_0_1 UHJKI XPOS_hp 134 df1$score < df2$score 
##2 B_1_3 NBVFR LKJ_mm 543 df1$score > df2$score 
##3 C_9_0 TRFDA NBV_lp 80     <NA> 
##4 D_9_1 KOIUA TRE_po 212 df1$score < df2$score 
##5 E_0_1 SDFRQ QAS_np 300 df1$score == df2$score 
##6 E_0_1 SDKIJ JIT_mx 160 df1$score == df2$score 
##7 F_0_1 JKOPA TOZ_po 79     <NA> 

Проводит левый внешнее объединение df1 и df2 по T_id, U_id, and U_code. Это объединит две таблицы, где score от df1 составляет score.x, а score от df2 - score.y. Затем используйте mutate для создания столбца comp, который означает, что score.x больше, чем или равно score.y. Наконец, мы переименуем столбец score.x в score и удалим столбец score.y, чтобы сделать результат чистым для презентации.

Эквивалентная реализация с использованием базового-R является:

res <- merge(df1,df2,by=c("T_id","U_id","U_code"), all.x=TRUE) 
res$comp <- ifelse(res$score.x > res$score.y,"df1$score > df2$score",ifelse(res$score.x < res$score.y,"df1$score < df2$score","df1$score == df2$score")) 
res <- res[,c(1:4,6)] 
colnames(res) <- sub("score.x","score",colnames(res)) 

, который дает тот же результат. Если после этого вы хотите split это в результате кадр данных по comp:

split(res[,-5],res$comp) 
##$`df1$score < df2$score` 
## T_id U_id U_code score 
##1 A_0_1 UHJKI XPOS_hp 134 
##4 D_9_1 KOIUA TRE_po 212 
## 
##$`df1$score == df2$score` 
## T_id U_id U_code score 
##5 E_0_1 SDFRQ QAS_np 300 
##6 E_0_1 SDKIJ JIT_mx 160 
## 
##$`df1$score > df2$score` 
## T_id U_id U_code score 
##2 B_1_3 NBVFR LKJ_mm 543