У меня есть data.frame
с идентификаторами, состоящими из последовательности буквенно-цифровых символов (например, id = c(A001, A002, B013)
).Я искал простую функцию в stringr
или stirngi
, которая легко могла бы выполнить математику с этими строками (id + 1 должен вернуть c(A002, A003, B014)
).
Я сделал пользовательскую функцию, которая делает свое дело, однако у меня есть ощущение, что для достижения этого должен быть лучший / более эффективный / внутрипакетный способ.
str_add_n <- function(df, string, n, width=3){
string <- enquo(string)
## split the string using pattern
df <- df %>%
separate(!!string,
into = c("text", "num"),
sep = "(?<=[A-Za-z])(?=[0-9])",
remove=FALSE
) %>%
mutate(num = as.numeric(num),
num = num + n,
num = stringr::str_pad(as.character(num),
width = width,
side = "left",
pad = 0
)
) %>%
unite(next_string, text:num, sep = "")
return(df)
}
Давайте сделаемигрушка df
df <- data.frame(id = c("A001", "A002", "B013"))
str_add_n(df, id, 1)
id next_string
1 A001 A002
2 A002 A003
3 B013 B014
Опять же, это работает, мне интересно, есть ли лучший способ сделать это, все твики приветствуются!
ОБНОВЛЕНИЕ
Основано наиз предложенных ответов я провел некоторое тестирование, и похоже, что оба очень близки, я был бы склонен к str_add_n_2
(я изменил имя, чтобы можно было запускать оба, и принял предложение x<-as.character(x)
)
microbenchmark::microbenchmark(question = str_add_n(df, id, 1),
answer = df %>% mutate_at(vars(id), funs(str_add_n_2(., 1))),
string_add = df %>% mutate_at(vars(id), funs(string_add(as.character(.)))))
Что дает
Unit: milliseconds
expr min lq mean median uq
question 4.312094 4.448391 4.695276 4.570860 4.755748
answer 2.932146 3.017874 3.191262 3.117627 3.240688
string_add 3.388442 3.466466 3.699363 3.534416 3.682762
max neval cld
10.29253 100 c
8.24967 100 a
9.05441 100 b
Больше твиков приветствуются!