R: Эффективный способ заменить значения столбца на основе строк (может быть, case_when или какой-либо другой вид mutate)? - PullRequest
0 голосов
/ 02 апреля 2020

Есть ли более эффективный способ замены значений в столбцах на основе поиска строк в них?

prac <- data.frame(`External Placement` = c(NA, NA, "Spanish words We place outside of our company", NA, NA, "Spanish words We place outside of our company", "Spanish words We place outside of our company", "Spanish words We place outside of our company", NA, "Spanish words We place outside of our company"),
             `Internal Placement` = c(NA, NA, "Spanish words we place inside of our organisation", NA, "Spanish words we place inside of our organisation", "Spanish words we place inside of our organisation", NA, NA, NA, NA),
             `None of the above` = c("Ninguno none", "Ninguno none", NA, NA, NA, NA, NA, NA, NA, NA))

Это пример данных. Я использовал серию if / else, чтобы получить значения, которые я хочу, но я долго пытался найти способ сделать это с помощью mutate, case_when и так далее, чтобы сделать меньше повторений. Есть ли способ лучше? Это то, что я сделал до сих пор:

prac$`Vocational Training` <- ifelse(grepl("vocational training$", prac$`Vocational Training`),
                                 "Vocational training", NA)
prac$`External Placement` <- ifelse(grepl("outside of our company$", prac$`External Placement`),
                                    "External placement", NA)
prac$`Internal Placement` <- ifelse(grepl("inside our organisation$", prac$`Internal Placement`),
                                    "Internal placement", NA)  
prac$`None of the Above` <- ifelse(grepl("^Ninguno", prac$`None of the Above`), "None or other", NA)

Ответы [ 2 ]

0 голосов
/ 02 апреля 2020

Это зависит от того, какая эффективность вы хотите - это вычислительная эффективность (время вычислений) или эффективность программирования (количество используемых строк)

С точки зрения эффективности программирования будет очень трудно победить data.table решение. Я могу предложить вам следующее:

prac <- data.frame(`External Placement` = c(NA, NA, "Spanish words We place outside of our company", NA, NA, "Spanish words We place outside of our company", "Spanish words We place outside of our company", "Spanish words We place outside of our company", NA, "Spanish words We place outside of our company"),
                   `Internal Placement` = c(NA, NA, "Spanish words we place inside of our organisation", NA, "Spanish words we place inside of our organisation", "Spanish words we place inside of our organisation", NA, NA, NA, NA),
                   `None of the Above` = c("Ninguno none", "Ninguno none", NA, NA, NA, NA, NA, NA, NA, NA))

library(data.table)

list_conditions <- c(#"Vocational.Training" = "vocational training$",
  "External.Placement" = "outside of our company$",
  "Internal.Placement" = "inside our organisation$",
  "None.of.the.Above" = "^Ninguno")


dt <- data.table(prac)

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

dt <- lapply(seq_len(length(list_conditions)), function(i) {

  var <- names(list_conditions)[i]
  cond <- list_conditions[i]
  val <- gsub("\\.","", var)
  dt[, 'tempcol' := NA_character_]
  dt[grepl(as.character(cond), get(var)), tempcol := as.character(val)]
  dt[,c(var) := tempcol]

})
dt <- dt[[length(dt)]]
dt[,'tempcol' := NULL]

Строка dt <- dt[[length(dt)]] здесь, потому что R возвращает список, но мы интересует только его последний элемент (последнее обновление для фрейма данных). Вы можете обобщить эту программу, если предпочитаете создавать новые столбцы, а не переписывать существующие.

Вывод:

dt
    External.Placement Internal.Placement None.of.the.Above
 1:               <NA>               <NA> None of the Above
 2:               <NA>               <NA> None of the Above
 3: External Placement               <NA>              <NA>
 4:               <NA>               <NA>              <NA>
 5:               <NA>               <NA>              <NA>
 6: External Placement               <NA>              <NA>
 7: External Placement               <NA>              <NA>
 8: External Placement               <NA>              <NA>
 9:               <NA>               <NA>              <NA>
10: External Placement               <NA>              <NA>
0 голосов
/ 02 апреля 2020

Может быть, вы можете попробовать код, как показано ниже

v <- c("outside of our company$","inside our organisation$","^Ninguno")
r <- c("External placement","Internal placement","None or other")

prac[]<- mapply(function(x,y) ifelse(x,y,NA),
                data.frame(mapply(grepl, v,prac)),
                r)

такой, что

> prac
   External.Placement Internal.Placement None.of.the.above
1                <NA>               <NA>     None or other
2                <NA>               <NA>     None or other
3  External placement               <NA>              <NA>
4                <NA>               <NA>              <NA>
5                <NA>               <NA>              <NA>
6  External placement               <NA>              <NA>
7  External placement               <NA>              <NA>
8  External placement               <NA>              <NA>
9                <NA>               <NA>              <NA>
10 External placement               <NA>              <NA>

ДАННЫЕ

prac <- structure(list(External.Placement = structure(c(NA, NA, 1L, NA, 
NA, 1L, 1L, 1L, NA, 1L), .Label = "Spanish words We place outside of our company", class = "factor"), 
    Internal.Placement = structure(c(NA, NA, 1L, NA, 1L, 1L, 
    NA, NA, NA, NA), .Label = "Spanish words we place inside of our organisation", class = "factor"), 
    None.of.the.above = structure(c(1L, 1L, NA, NA, NA, NA, NA, 
    NA, NA, NA), .Label = "Ninguno none", class = "factor")), class = "data.frame", row.names = c(NA, 
-10L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...