преобразовать символьный столбец, а затем разделить его на несколько новых логических столбцов с помощью r mutate

#r #data-cleaning #dplyr

#r #очистка данных #dplyr

Вопрос:

Я пытаюсь разделить столбец flags на несколько новых столбцов в r, используя mutate_at, а затем отдельные функции. Я упростил и очистил свое решение, как показано ниже, однако я получаю сообщение об ошибке, которое указывает на то, что в мою функцию передается весь столбец данных, а не каждая строка в отдельности. Является ли это нормальным поведением, которое просто требует, чтобы я перебирал каждый элемент x внутри моей функции? или я неправильно вызываю функцию mutate_at?

пример данных:

 dataVariable <- data.frame(c_flags = c(".q.q.q","y..i.o","0x5a",".lll.."))
  

функции:

 dataVariable <- read_csv("...",
  col_types = cols(
    c_date = col_datetime(format = ""),
    c_dbl = col_double(),
    c_flags = col_character(),
    c_class = col_factor(c("a", "b", "c")),
    c_skip = col_skip()
))


funTranslateXForNewColumn <- function(x){
    binary = ""
    if(startsWith(x, "0x")){
        binary=hex2bin(x)
    } else {
        binary = c(0,0,0,0,0,0)
        splitFlag = strsplit(x, "")[[1]]
        for(i in splitFlag){
          flagVal = 1
          if(i=="."){
            flagVal = 0
          }
          binary=append(binary, flagVal)
        }
    }
    return(paste(binary[4:12], collapse='' ))
}



mutate_at(dataVariable, vars(c_flags), funs(funTranslateXForNewColumn(.)))

separate(dataVariable, c_flags, c(NA, "flag_1","flag_2","flag_3","flag_4","flag_5","flag_6","flag_7","flag_8","flag_9"), sep="")
  

Ошибка, которую я получаю, заключается в следующем:

 Warning messages:
1: Problem with `mutate()` input `c_flags`.
i the condition has length > 1 and only the first element will be used
  

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

Комментарии:

1. и каков ваш ожидаемый результат для совместно используемых данных? Должен быть лучший способ сделать это, чем for цикл.

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

Ответ №1:

Аналогично логике OP, но, возможно, короче :

 dataVariable$binFlags <- sapply(strsplit(dataVariable$c_flags, ''), function(x)
                                 paste(as.integer(x != '.'), collapse = ''))
  

Если вы хотите сделать это, используя dplyr , мы можем реализовать ту же логику, что и :

 library(dplyr)

dataVariable %>%
  mutate(binFlags = purrr::map_chr(strsplit(c_flags, ''), 
                     ~paste(as.integer(. != '.'), collapse = '')))

#  c_flags binFlags
#1  .q.q.q   010101
#2  y..i.o   100101
#3  .lll..   011100
  

mutate_at / across используется, когда вы хотите применить функцию к нескольким столбцам. Более того, я не вижу здесь, что вы создаете только один новый двоичный столбец, а не несколько новых столбцов, как указано в вашем сообщении.

Комментарии:

1. Я упростил свой код для публикации. Реальные данные уже имеют некоторые значения в шестнадцатеричном формате, которые можно легко перевести в двоичный. Функция обрабатывает оба случая. Затем я использую: separate(dataVariable, c_flags, c(NA, «flag_1», «flag_2», «flag_3», «flag_4», «flag_5», «flag_6», «flag_7», «flag_8», «flag_9″), sep =»»)

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

Ответ №2:

Я смог получить желаемый результат, заменив функцию mutate_at на:

 dataVariable$binFlags <- mapply(funTranslateXForNewColumn, dataVariable$c_flags)
  

Однако я хочу знать, как правильно использовать функцию mutate_at .

заслуга: https://datascience.stackexchange.com/questions/41964/mutate-with-custom-function-in-r-does-not-work

Приведенная выше ссылка также включает в себя решение для запуска этой функции, которое заключается в векторизации функции:

 v_funTranslateXForNewColumn <- Vectorize(funTranslateXForNewColumn)
mutate_at(dataVariable, vars(c_flags), funs(v_funTranslateXForNewColumn(.)))