Проблема с индексацией с использованием двух фреймов данных в R - PullRequest
0 голосов
/ 13 октября 2018

У меня есть два фрейма данных Table_1 и Table_2, и мне нужно добавить столбец "index" в Table_2, где значение 1 для совпадающих строк от Table_1 и 0 для других.

По сути, мне нужно сопоставить столбцы "Pol", "CTY", "STATE" и "CRP" из Table_1 и "STATE", "CTY", "CRP" и "Pol_No" из Table_2.

Я предпочитаю метод data.table.

 Table_1:

 Pol      Cty    Avg    STATE   CRP
 85010    23     1123    MO     11
 75022    23     1123    MO     11
 35014   143     450     MO     11
.
.

Table_2:

STATE   CTY    CRP   Pol_No   Plan   Price 
AL      1      11    150410   90     4563
AL      1      21    45023    90     5402
MO    143      11    85010    90     2522
.
.

Желаемый результат, как показано ниже.

Table_2:

STATE   CTY    CRP   Pol_No   Plan   Price  Index
AL      1      11    150410   90     4563     0
AL      1      21    45023    90     5402     0
MO    143      11    85010    90     2522     1
.
.

Как я могу добиться этого R.?

Любая помощь приветствуется.

Спасибо.

Ответы [ 3 ]

0 голосов
/ 13 октября 2018

Это не очень хорошее решение, но оно работает для data.table.Вам нужен sqldf, который работает для фреймов данных и таблиц данных.

library(data.table)
df1<-data.table(Pol=c(85010,75022,35014),Cty=c(23,23,143), Avg=c(1123,1123,450),STATE=c("MO","MO","MO"), CRP=c(11,11,11))

df2=data.table(STATE=c("AL","AL","MO"),CTY=c(1,1,143),CRP=c(11,21,11),Pol_No=c(150410,45023,85010),Plan=c(90,90,90),Price=c(4563,5402,2522))

library(sqldf)
#left join
df<-sqldf("select df2.STATE,df2.CTY,df2.CRP,df2.Pol_No,df2.Plan,df2.Price,df1.Pol from df2 left join df1 on df1.Pol=df2.Pol_No")
#create index
df$index<-ifelse(is.na(df$Pol),0,1)

#delete extra column
df$Pol<-NULL 

> df
  STATE CTY CRP Pol_No Plan Price index
1    AL   1  11 150410   90  4563     0
2    AL   1  21  45023   90  5402     0
3    MO 143  11  85010   90  2522     1
0 голосов
/ 13 октября 2018

Вот полностью решение для data.table:

 merge(t1,t2,by.x='Pol', by.y='Pol_No', all.y=TRUE)[,c('STATE.y','CTY', 'Cty', 'CRP.y',   'Pol',   'Plan',   'Price')]
#-----
   STATE.y CTY Cty CRP.y    Pol Plan Price
1:      AL   1  NA    21  45023   90  5402
2:      MO 143  23    11  85010   90  2522
3:      AL   1  NA    11 150410   90  4563
#--------
t3 <- merge(t1,t2,by.x='Pol', by.y='Pol_No', all.y=TRUE)[ ,
          c('STATE.y','CTY', 'Cty', 'CRP.y', 'Pol', 'Plan',   'Price')] 
t3[ , index := as.numeric(!is.na(Cty))]
t3
#--------
   STATE.y CTY Cty CRP.y    Pol Plan Price index
1:      AL   1  NA    21  45023   90  5402     0
2:      MO 143  23    11  85010   90  2522     1
3:      AL   1  NA    11 150410   90  4563     0

Чтобы получить имена столбцов сразу после merge(.. Я впервые посмотрел:

merge(t1,t2,by.x='Pol', by.y='Pol_No', all.y=TRUE)
      Pol Cty  Avg STATE.x CRP.x STATE.y CTY CRP.y Plan Price
1:  45023  NA   NA    <NA>    NA      AL   1    21   90  5402
2:  85010  23 1123      MO    11      MO 143    11   90  2522
3: 150410  NA   NA    <NA>    NA      AL   1    11   90  4563
0 голосов
/ 13 октября 2018

Я думаю, что это прямое соединение из нескольких столбцов:

library(dplyr)
t2 %>%
  left_join(transmute(t1, CTY=Cty, STATE, Index=1L), by=c("CTY", "STATE")) %>%
  mutate(Index = if_else(is.na(Index), 0L, Index))
#   STATE CTY CRP Pol_No Plan Price Index
# 1    AL   1  11 150410   90  4563     0
# 2    AL   1  21  45023   90  5402     0
# 3    MO 143  11  85010   90  2522     1

РЕДАКТИРОВАТЬ

Я пытался выучить data.table, подумалЯ бы попробовал.Мне кажется, немного неуклюже, я уверен, что есть способ упростить его.

t1 <- setDT(t1); t2 <- setDT(t2)

Для удобства установите имена столбцов одинаковыми (яв противном случае я не уверен, как легко это сделать) ... один - "Cty", другой - "CTY".Сделайте их одинаковыми.

colnames(t1)[2] <- "CTY"

Теперь, объединение.

t1[,.(CTY,STATE,CRP,Index=1),][t2,on=c("CTY","STATE","CRP")]
#    CTY STATE CRP Index Pol_No Plan Price
# 1:   1    AL  11    NA 150410   90  4563
# 2:   1    AL  21    NA  45023   90  5402
# 3: 143    MO  11     1  85010   90  2522

Примечания:

  • первая скобочная операция выбирает только три соединениястолбцы и назначение четвертого, Index;
  • , фактическое объединение во втором брекет-операторе, первое - просто выделение
  • , обычно data.table ops работают с побочным эффектом,но не слияния или выборки, подобные этому, поэтому он возвращает их без изменения базовой структуры;для этого нам нужно сохранить его (возможно, в t2)

Это близко ... теперь просто обновите поле Index, так как оно либо 1, гдеданные сосуществуют или NA в противном случае.

t2 <- t1[,.(CTY,STATE,CRP,Index=1),][t2,on=c("CTY","STATE","CRP")]
t2[,Index := as.integer(!is.na(Index)),]
t2
#    CTY STATE CRP Index Pol_No Plan Price
# 1:   1    AL  11     0 150410   90  4563
# 2:   1    AL  21     0  45023   90  5402
# 3: 143    MO  11     1  85010   90  2522

Данные:

t1 <- read.table(header=TRUE, stringsAsFactors=FALSE, text='
 Pol      Cty    Avg    STATE   CRP
 85010    23     1123    MO     11
 75022    23     1123    MO     11
 35014   143     450     MO     11')
t2 <- read.table(header=TRUE, stringsAsFactors=FALSE, text='
STATE   CTY    CRP   Pol_No   Plan   Price 
AL      1      11    150410   90     4563
AL      1      21    45023    90     5402
MO    143      11    85010    90     2522')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...