R найти строки, начинающиеся с группы цифр c символов - PullRequest
1 голос
/ 21 марта 2020

Я пытаюсь исправить ошибки ввода почтового индекса, используя первые два префикса. В качестве воспроизводимого примера (гипотетически) предположим, что почтовые индексы начинаются с 01, 02, 03 и 04 - MA, но мои данные содержат ошибку, как показано ниже.

ma_zip <- c("01", "02", "03", "04")

df <- data.frame(zip = c("01100", "02223", "04332", "03234"),
                 state = c("MA", "NJ", "NY", "NY")) %>%
  mutate(zip = as.character(zip),
         state = as.character(state))

Я попытался исправить ошибку двумя способами. В первом (и грубой силе) подходе я исправил его один за другим и получил желаемый результат.

df_cleaned1 <- df %>%
  mutate(state = replace(state, startsWith(zip, "02"), "MA"),
         state = replace(state, startsWith(zip, "03"), "MA"),
         state = replace(state, startsWith(zip, "04"), "MA"))

> df_cleaned1
    zip state
1 01100    MA
2 02223    MA
3 04332    MA
4 03234    MA

Но это не самое смешное, поскольку мне приходится многократно копировать и вставлять. Поэтому я попробовал следующее, но это, похоже, не работает (также не выдается сообщение об ошибке).

df_cleaned2 <- df %>%
  mutate(state = replace(state, startsWith(zip, paste(ma_zip, collapse="|")), "MA"))

> df_cleaned2
    zip state
1 01100    MA
2 02223    NJ
3 04332    NY
4 03234    NY

Есть ли эффективный способ получения df_cleaned1, избегая подхода грубой силы? (Не обязательно использовать функцию startWith)

Ответы [ 4 ]

3 голосов
/ 21 марта 2020

Мы можем использовать str_sub из stringr, чтобы получить первые 2 символа и использовать это с %in%

library(dplyr)
library(stringr)
df %>%
     mutate(state = replace(state, str_sub(zip, 1, 2) %in% ma_zip,
              'MA'))

Или другой параметр - регулярное выражение

df %>%
    mutate(state = replace(state, str_detect(zip, str_c("^(", str_c(ma_zip, collapse="|"), ")")), 'MA'))
#   zip state
#1 01100    MA
#2 02223    MA
#3 04332    MA
#4 03234    MA
3 голосов
/ 21 марта 2020

Возможно:

library(dplyr)

df %>% mutate(state = replace(state, substr(zip, 1, 2) %in% ma_zip, 'MA'))

Вывод:

    zip state
1 01100    MA
2 02223    MA
3 04332    MA
4 03234    MA
1 голос
/ 22 марта 2020

Другой вариант - использовать grepl вместо startsWith. Вам нужно будет создать следующий шаблон ^01|^02|^03|^04, который можно сделать с помощью функции вставки с некоторыми изменениями вашего подхода (@ qnp1521):

df_cleaned2 <- df %>% mutate(state = replace(state, grepl(paste("^",ma_zip, collapse ="|",sep=""),zip), "MA"))

df_cleaned2
1 01100    MA
2 02223    MA
3 04332    MA
4 03234    MA
1 голос
/ 21 марта 2020

Вот некоторые базовые решения R

df <- within(df, state <- replace(state,gsub("(\\w{2}).*","\\1",zip) %in% ma_zip,"MA"))

или

df <- within(df, state <- replace(state,substr(zip,1,2) %in% ma_zip,"MA"))

такие, что

> df
    zip state
1 01100    MA
2 02223    MA
3 04332    MA
4 03234    MA
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...