我正在读一本书,我在R中遇到了这个函数。这个函数基本上找出输入字符串中的模式,其最小阈值为3。
vec <- "da0abcab0abcaab0d0"
find_rep_path <- function(vec, reps) {
regexp <- paste0(c("(.+)", rep("\\1", reps - 1L)), collapse = "")
match <- regmatches(vec, regexpr(regexp, vec, perl = TRUE))
substr(match, 1, nchar(match) / reps)
}
vals <- unique(strsplit(vec, "")[[1]])
str <- NULL
for (i in seq.int(nchar(vec))) {
x <- vec
for (v in vals) {
substr(x, i, i) <- v
tmp <- find_rep_path(x, 3)
if (length(tmp) > 0)
str <- c(str, tmp)
}
}
nc <- nchar(str)
unique(str[which(nc == max(nc))])
现在,我希望将此函数转换为如下形式: 功能( “da0abcab0abcaab0d0”)。这意味着,我可以轻松地将字符串直接传递给函数,而不是在原始函数中对其进行硬编码。我怎么修改这个? 我知道这是一个初学者的问题,但就R而言,我现在完全在海上。请帮忙!
答案 0 :(得分:1)
我不知道它是如何硬编码的。但是,如果这就是你的意思,你可以将你的代码包装成一个函数吗?
# Function 1
find_rep_path <- function(vec, reps) {
regexp <- paste0(c("(.+)", rep("\\1", reps - 1L)), collapse = "")
match <- regmatches(vec, regexpr(regexp, vec, perl = TRUE))
substr(match, 1, nchar(match) / reps)
}
# Function 2
foo <- function(vec) {
vals <- unique(strsplit(vec, "")[[1]])
str <- NULL
for (i in seq.int(nchar(vec))) {
x <- vec
for (v in vals) {
substr(x, i, i) <- v
tmp <- find_rep_path(x, 3)
if (length(tmp) > 0)
str <- c(str, tmp)
}
}
nc <- nchar(str)
return(unique(str[which(nc == max(nc))]))
}
vec <- "da0abcab0abcaab0d0"
foo(vec)
#[1] "0ab" "abc"
<强> EDIT1 强>
要获得匹配位置,您可以使用gregexr
:
a <- foo(vec)
gregexpr(a[1], vec)
#[[1]]
#[1] 3 9
#attr(,"match.length")
#[1] 3 3
#attr(,"useBytes")
#[1] TRUE
这告诉您a[1]
("0ab"
)在位置3和9的vec
中匹配。运行?gregexpr
以获取更多信息。
<强> EDIT2 强>
要将此信息添加到每个匹配项,我们可以执行类似
的操作bar <- function(vec) {
m <- foo(vec)
ans <- sapply(m, gregexpr, vec, fixed = TRUE)
ans <- lapply(ans, function(x) {attributes(x) <- NULL; x})
return(ans)
}
bar(vec)
#$`0ab`
#[1] 3 9
#
#$abc
#[1] 4 10