Как добавить начальные нули на основе шаблона?

#r

Вопрос:

У меня есть следующий набор данных и этот код, который добавит ведущие нули к значениям, которые идут с тире, оставляя их с шаблоном XXXXXXXX-XX. это частично работает:

 df.direccionamientos = structure(list(D_CodSerTecAEntregar = c("139",
                                                               "20018219-1", 
                                                               "2019-1", 
                                                               "20018219-1"
                                                               
                                                               )), 
                                 .Names = "D_CodSerTecAEntregar", 
                                 row.names = c(NA, -4L),
                                 class = c("tbl_df", "tbl", "data.frame"))

#Leading zeroes
df.direccionamientos$D_CodSerTecAEntregar1 <- ifelse(grepl('-', df.direccionamientos$D_CodSerTecAEntregar), 
                                                      do.call(sprintf, c(fmt = 'd-d', 
                                                                         read.table(text = df.direccionamientos$D_CodSerTecAEntregar,
                                                                                    header = FALSE, sep="-", 
                                                                                    fill = TRUE))), 
                                                     df.direccionamientos$D_CodSerTecAEntregar)
 

выход1

Но это усложняется, когда новое значение с другим шаблоном проходит через код (см. строку 5 из нового набора данных). Это портит все вновь созданные коды:

 df.direccionamientos = structure(list(D_CodSerTecAEntregar = c("139",
                                                               "20018219-1", 
                                                               "2019-1", 
                                                               "20018219-1",
                                                               "1R1033181000100"
                                                               
                                                               )), 
                                 .Names = "D_CodSerTecAEntregar", 
                                 row.names = c(NA, -5L),
                                 class = c("tbl_df", "tbl", "data.frame"))


#Leading zeroes
df.direccionamientos$D_CodSerTecAEntregar1 <- ifelse(grepl('-', df.direccionamientos$D_CodSerTecAEntregar), 
                                                      do.call(sprintf, c(fmt = 'd-d', 
                                                                         read.table(text = df.direccionamientos$D_CodSerTecAEntregar,
                                                                                    header = FALSE, sep="-", 
                                                                                    fill = TRUE))), 
                                                     df.direccionamientos$D_CodSerTecAEntregar)
 

выход2

Ответ №1:

Проблема в том, что при наличии букв во входных данных поля не могут быть автоматически преобразованы в целые числа до sprintf их применения. Вот упрощенное использование tidyr , dplyr которое исправляет проблему (и должно быть более эффективным):

 library(tidyr)
library(dplyr)

df.direccionamientos %>%
  separate(D_CodSerTecAEntregar, sep = "-", into = c("a", "b"), remove = FALSE, fill = "right") %>%
  mutate(
    across(c(a, b), as.numeric),
    result = ifelse(!is.na(b), sprintf("d-d", a, b), D_CodSerTecAEntregar)
  ) %>%
  select(-a, -b)
# # A tibble: 5 x 2
#   D_CodSerTecAEntregar result         
#   <chr>                <chr>          
# 1 139                  139            
# 2 20018219-1           20018219-01    
# 3 2019-1               00002019-01    
# 4 20018219-1           20018219-01    
# 5 1R1033181000100      1R1033181000100
 

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

1. Спасибо. мне нравится ваш подход, но я получаю ошибки при попытке запустить образец набора данных. Error: Problem with мутировать()` столбец result .` result = ifelse(!is.na(b), sprintf("d-d", a, b), D_CodSerTecAEntregar) .` x invalid format 'd'; use format %f, %e, %g or %a for numeric objects

2. Хм, попробуй переодеться as.numeric as.integer .