我有一个data.frame
,id由字母数字字符序列组成(例如,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
型
欢迎更多的调整!
3条答案
按热度按时间mfpqipee1#
这里有一个方法与
gsubfn
字符串
你可以把它变成一个函数
型
ebdffaop2#
我建议基于字符串的 vector 来定义函数更容易,而不是硬编码它来查找框架中的列;对于后者,您总是可以使用类似
mutate_at(vars(id,...), funs(str_add_n))
的东西。字符串
如果在框架中:
型
警告:这需要真正的
character
,而不是factor
.一种可能的防御策略可能是在函数定义中添加x <- as.character(x)
。mutate_at
已被取代,across
的首选用途是:型
或更直接
型
gjmwrych3#
下面是
str_replace
的一个变体,它来自tidyverse
的一部分stringr
包:字符串
或者直接在mutate语句中不带函数:
型