Заменить несколько совпадений одной и той же строки разными шаблонами в R - PullRequest
0 голосов
/ 05 марта 2020

У меня есть набор фреймов данных, где в каждом есть несколько вхождений одной и той же строки в столбце, но они действительно отражают разные наблюдения.

library(dplyr)
govs <- c("Government", "Federal", "General government", "Government enterprises", "State and local", 
          "General government", "Government enterprises")
df <- data.frame("gov_levels" = govs, revenue = rnorm(7, mean = 1000, sd = 50))
df

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

    df %>% 
    mutate(gov_levels = stri_replace_first_fixed(str = gov_levels, pattern = "General government", 
                                    replacement = c("Federal general government", 
                                                    "State and local general government")))

, но он не согласован в зависимости от того, находится ли «Сектор государственного управления» в четной или нечетной строке, как показано на рисунке, когда я удаляю первую строку перед изменением:

    df %>%
    filter(gov_levels != "Government") %>%
    mutate(gov_levels = stri_replace_first_fixed(str = gov_levels, pattern = "General government", 
                                           replacement = c("Federal general government", 
                                                           "State and local general government"))) 

В результате замены происходят в неправильном порядке. Я ищу способ применять это последовательно, чтобы он не зависел от положения строк заменяемых строк. Таким образом, первый матч всегда будет заменен на Федеральное Государственное управление, а второй будет всегда заменяться Государственное и местное Государственное управление.

ОБНОВЛЕНИЯ НА ОСНОВЕ GEORGE'S ОТВЕТ. Список фреймов данных с некоторыми несоответствиями:

govs <- c("Government", "Federal", "General government", "Government enterprises", "State and local", 
          "General government", "Government enterprises", NA, NA)

df1 <- data.frame("col_1" = "col1data", "gov_levels" = govs, revenue = c(rnorm(7, mean = 100, sd = 50), NA, NA), stringsAsFactors = FALSE)
df2 <- data.frame("col_1" = "col1data", "gov_types" = govs, revenue = c(rnorm(7, mean = 100, sd = 50), NA, NA), stringsAsFactors = FALSE)

df2 <- df2 %>%
       filter(gov_types != "Government")

df_list <- list(df1, df2)

И реализация решения Джорджа с помощью lapply для решения других упомянутых мной проблем - мне любопытно, если есть лучший способ подойти к этому?


newlevels_gen <- c("Federal general government", "State and local general government")

df_list <- lapply(df_list, 
                  function(x) {x[, 2] <- as.factor(x[, 2]) 
                               return(x)
                               }
                  )

df_list <- lapply(df_list, function(x) {levels(x[,2]) <- c(levels(x[,2]), newlevels_gen)
                                        return(x)
                                        }
                  )

df_list_clean_a <- lapply(df_list, function(x) {x[,2][!is.na(x[,2]) & x[,2] == "General government"] <- newlevels_gen 
                                               return(x)
                                               } 
                         )

1 Ответ

0 голосов
/ 05 марта 2020

Достигает ли это вашей цели? Просто замените элементы, которые соответствуют вашему условию, на требуемый вектор строки. Но сначала вам нужно добавить к разрешенным уровням для вашего фактора, или вы получите ошибку.

# First define a string containing the new levels for the 'gov_levels' factor
newlevels <- c("Federal general government", "State and local general government")

# Then add them so that they are allowed as factor levels
levels(df$gov_levels) <- c(levels(df$gov_levels), newlevels)

# Now just replace the values where 'gov_levels' is "General government" with the new string
# They will naturally be assigned in the same order they occur in the dataset
df$gov_levels[df$gov_levels=="General government"] <- newlevels

Конечно, это будет работать, только если есть ровно два случая, но я думаю, из вашего вопроса это это тот случай? Если их два или меньше, мы можем настроить последнюю строку для подсчета необходимого количества вхождений.

Редактировать

Если вектор gov_levels является символьным вектором, а не фактор, тогда вам не нужно беспокоиться об уровнях, и вы можете просто сделать:

df$gov_levels[df$gov_levels=="General government"] <- 
      c("Federal general government", "State and local general")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...