Объедините уровни факторов с соответствием нечеткой / частичной символьной строки в R - PullRequest
0 голосов
/ 07 ноября 2019

У меня есть набор данных, который включает в себя DMA (обозначенная рыночная зона), но многие из DMA отображаются как два разных уровня, потому что DMA усечено, например, DMA "Abilene-Sweetwater, TX" иногда отображается как "Abilene-Sweetw "

Ниже приведен фрагмент набора данных:

dma <- c("Abilene-Sweetw", "Abilene-Sweetwater, TX", 
         "Albany, GA", "Albany, GA", 
         "Albany-Schenec", "Albany-Schenec", 
         "Albany-Schenectady-Troy, NY", "Albany-Schenectady-Troy, NY")
cost <- c(0.46, 0.46, 0.45, 0.45, 0.32, 0.32, 0.32, 0.32)

DMA.df <- data.frame(dma, cost)

DMA.df
dma cost
1              Abilene-Sweetw 0.46
2      Abilene-Sweetwater, TX 0.46
3                  Albany, GA 0.45
4                  Albany, GA 0.45
5              Albany-Schenec 0.32
6              Albany-Schenec 0.32
7 Albany-Schenectady-Troy, NY 0.32
8 Albany-Schenectady-Troy, NY 0.32

Поиск в SO и других решениях, которые показывают, как вручную объединить несколько уровней факторовв одну. Очевидно, я не хочу делать это вручную.

Я ищу способ исправить усеченный DMA и превратить его в «полный» DMA (город -...-, штат). Одна из благодатных сторон заключается в том, что в усечении есть шаблон - он обрезается на 14 букв. Решение должно соответствовать всем 14 символам, потому что многие DMA начинаются с с одинаковыми именами (например, "Albany, GA" и "Albany -..., NY").

Поместите другойКстати, мне нужно найти все усеченные DMA, которые соответствуют полным DMA, и превратить усеченный DMA в полный DMA.

Пример DF должен выглядеть следующим образом:

             dma cost
1      Abilene-Sweetwater, TX 0.46
2      Abilene-Sweetwater, TX 0.46
3                  Albany, GA 0.45
4                  Albany, GA 0.45
5 Albany-Schenectady-Troy, NY 0.32
6 Albany-Schenectady-Troy, NY 0.32
7 Albany-Schenectady-Troy, NY 0.32
8 Albany-Schenectady-Troy, NY 0.32

Заранее спасибо за любые предложения.

1 Ответ

0 голосов
/ 12 ноября 2019

Самое простое решение с использованием Base r:: substring и merge и dplyr::select и mutate:

#sample (and problematic) df with some DMAs truncated and others full-length
dma <- c("Abilene-Sweetw", "Abilene-Sweetwater, TX", 
         "Albany, GA", "Albany, GA", 
         "Albany-Schenec", "Albany-Schenec", 
         "Albany-Schenectady-Troy, NY", "Albany-Schenectady-Troy, NY")
cost <- c(0.46, 0.46, 0.45, 0.45, 0.32, 0.32, 0.32, 0.32)


DMA.df <- data.frame(dma, cost, stringsAsFactors = FALSE)
                         dma cost
1              Abilene-Sweetw 0.46
2      Abilene-Sweetwater, TX 0.46
3                  Albany, GA 0.45
4                  Albany, GA 0.45
5              Albany-Schenec 0.32
6              Albany-Schenec 0.32
7 Albany-Schenectady-Troy, NY 0.32
8 Albany-Schenectady-Troy, NY 0.32

#create a column where ALL the DMAs are truncated to the same length
DMA.df <- DMA.df %>% 
  mutate(dma_truncated = substring(dma, 1, 13)) %>% 
  select(-dma) #drop the orginal 'DMA' column
cost dma_truncated
1 0.46 Abilene-Sweet
2 0.46 Abilene-Sweet
3 0.45    Albany, GA
4 0.45    Albany, GA
5 0.32 Albany-Schene
6 0.32 Albany-Schene
7 0.32 Albany-Schene
8 0.32 Albany-Schene

#Create a lookup table where the truncated DMA is paired with the full DMA
dma_master <- c("Abilene-Sweetwater, TX",  
                "Albany, GA", 
                "Albany-Schenectady-Troy, NY")
dma_truncated <- substring(dma_master, 1, 13)
DMA_lookup.df <- data.frame(dma_truncated, dma_master, stringsAsFactors = FALSE)

dma_truncated                  dma_master
1 Abilene-Sweet      Abilene-Sweetwater, TX
2    Albany, GA                  Albany, GA
3 Albany-Schene Albany-Schenectady-Troy, NY


#Use MERGE to create the desired column of 'DMA' in the original DF
full_DMA.df <- merge(DMA_lookup.df, DMA.df, by='dma_truncated') %>% 
  select(-dma_truncated) #drop the truncated DMA column

dma_master cost
1      Abilene-Sweetwater, TX 0.46
2      Abilene-Sweetwater, TX 0.46
3 Albany-Schenectady-Troy, NY 0.32
4 Albany-Schenectady-Troy, NY 0.32
5 Albany-Schenectady-Troy, NY 0.32
6 Albany-Schenectady-Troy, NY 0.32
7                  Albany, GA 0.45
8                  Albany, GA 0.45

Это сообщение SO, которое в основном решило мою проблему: Как сделать vlookupи заполнить (как в Excel) в R?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...