将函数转换为直接在r中接受输入

时间:2014-06-24 12:07:17

标签: r pattern-matching

我正在读一本书,我在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而言,我现在完全在海上。请帮忙!

1 个答案:

答案 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