为什么我的函数意外返回NULL?

时间:2014-09-07 09:53:54

标签: r

reps <- function(s, n) paste(rep(s, n), collapse = "") # repeat s n times

find.string <- function(string, th = 3, len = floor(nchar(string)/th)) {        
    for(sublen in len:1) 
    {
        for(inlen in 0:sublen) 
        {
            pat <- paste0("((.{", sublen-inlen, "})(.)(.{", inlen, "}))", reps("(\\2.\\4)", th-1))
            r <- regexpr(pat, string, perl = TRUE)
            if (attr(r, "capture.length")[1] > 0)
            {
                if (r > 0) 
                {
                    substring(string, r, r + attr(r, "capture.length")[1] - 1)
                }  
            }
        }             
    }             
}

为什么这段代码不起作用?基本上,此代码将接受输入字符串110111111并输出仅满足一个约束的所有模式:

连续出现至少3次。

然而,除此之外,它还将输出具有1个字符的抖动的模式,即类似110的模式,因为它除了在最后位置之外连续三次出现。但是,这只是输出NULL。另一个例子可以是:a0cc0vaaaabaaadbaaabbaa00bvw。此处,其中一个输出为aaaab

编辑:输入可以是包含字符或数字的字符串。此外,匹配的最小长度应至少为2.并且是,匹配重叠。此外,输入的格式为:

find.string("a0cc0vaaaabaaadbaaabbaa00bvw")` or `find.string("110111111")

1 个答案:

答案 0 :(得分:1)

我没有深入研究你的函数的逻辑,但有一个明显的原因,它有时会返回NULL。如果您没有明确使用return函数,R函数将返回它们评估的最后一个表达式。

sublen等于1(外循环)而inlen等于sublen(内循环)时会发生这种情况。如果attr(r, "capture.length")[1] > 0r > 0,则返回的值为substring(string, r, r + attr(r, "capture.length")[1] - 1)。如果不满足其中一个条件,则if函数返回NULL,因此find.strings返回NULL

您可以通过一个更简单的示例了解其工作原理:

f <- function() if(FALSE) 1
print(f())
## NULL

您需要将每个循环的结果存储在变量中,然后返回。


其他一些明显的代码改进:

  1. 您可以使用逻辑和if语句组合在一起。

    if (attr(r, "capture.length")[1] > 0 && r > 0)

  2. regexpr是矢量化的,因此您可以摆脱内部循环,并加快代码速度。