Как обновить имя на основе состояния другого столбца (Очистка данных) - PullRequest
0 голосов
/ 04 апреля 2020

У меня есть df ниже

df <- data.frame(LASTNAME = c("Robinson", "Anderson", "Beckham", "Wickham", "Carlos", "Robinson", "Beckham", "Anderson", "Carlos"),
                 FIRSTNAME = c("David", "Adi", "Joan", "Kesley", "Anberto", "Dave", "Joana", "Adien", "An"))

df <- data.frame(lapply(df, as.character), stringsAsFactors = FALSE)

Некоторые имена не соответствуют друг другу. Я хочу найти и заменить эти. Но когда я помещаю это в функцию, это не работает. Еще одна вещь, мои данные большие. Есть сотни имен, так что есть ли лучшие способы сделать это. Мой код работает хорошо, когда он один (не в функции), но я не смог найти способ сделать это, если у меня есть 100 имен, которые нужно найти и заменить. Я нашел ссылку здесь , но не решил мою проблему. Мы ценим любые предложения.

fil_name <- function(last,first,alternative){
  df %>% 
    mutate(FIRSTNAME = ifelse(LASTNAME == "last" & FIRSTNAME == "first", "alternative", FIRSTNAME))
}
fil_name(Robinson,Dave,David)

Ожидаемый результат:

 LASTNAME   FIRSTNAME
1 Robinson     David
2 Anderson     Adien
3  Beckham     Joana
4  Wickham    Kesley
5   Carlos   Anberto
6 Robinson     David
7  Beckham     Joana
8 Anderson     Adien
9   Carlos   Anberto

Ответы [ 2 ]

1 голос
/ 05 апреля 2020

Другой подход состоит в том, чтобы создать отдельный фрейм данных, включающий альтернативные пары имен FIRSTNAME, объединить его с исходными данными и обновить FIRSTNAME для тех строк, где ALTNAME не равно NA.

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

# create data frame with a column to maintain original sort order
df <- data.frame(obs = 1:9,
                 LASTNAME = c("Robinson", "Anderson", "Beckham", "Wickham", "Carlos", "Robinson", "Beckham", "Anderson", "Carlos"),
                 FIRSTNAME = c("David", "Adi", "Joan", "Kesley", "Anberto", "Dave", "Joana", "Adien", "An"),
                 stringsAsFactors = FALSE)
# create firstname / altname pairs 
altnames <- data.frame(FIRSTNAME = c("Dave","Adi","Joan","An"),
                       ALTNAME = c("David","Adien","Joana","Anberto"),
                       stringsAsFactors = FALSE)
# merge by firstname, keeping all rows from original data frame
combined <- merge(df,altnames,by="FIRSTNAME",all.x=TRUE)
# update rows where ALTNAME is not NA
combined[!is.na(combined$ALTNAME),"FIRSTNAME"] <- combined[!is.na(combined$ALTNAME),"ALTNAME"]
# print the result, ordered by sequence in original data frame
combined[order(combined$obs),c("LASTNAME","FIRSTNAME")]

... и вывод:

> combined[order(combined$obs),c("LASTNAME","FIRSTNAME")]
  LASTNAME FIRSTNAME
6 Robinson     David
1 Anderson     Adien
7  Beckham     Joana
9  Wickham    Kesley
4   Carlos   Anberto
5 Robinson     David
8  Beckham     Joana
2 Anderson     Adien
3   Carlos   Anberto
> 
1 голос
/ 04 апреля 2020

Мы можем преобразовать в символ внутри функции, и она должна работать

fil_name <- function(df, last,first,alternative){

         last <- rlang::as_string(rlang::ensym(last))
         first <- rlang::as_string(rlang::ensym(first))
         alternative <- rlang::as_string(rlang::ensym(alternative))
      df %>% 
       dplyr::mutate(FIRSTNAME = case_when(LASTNAME ==  last & 
                FIRSTNAME == first ~ alternative, TRUE ~ FIRSTNAME))
    }
fil_name(df, Robinson,Dave,David)
...