2017-04-12 214 views
0

我已经创建了以下函数。 R应该返回1,但我没有给出任何结果?r函数不返回任何结果

phrasedis <- function(string, phrase1, phrase2,n) { 
    char1 <- unlist(gregexpr(phrase1,string)) 
    char2 <- unlist(gregexpr(phrase2,string)) 

    for (i in 1: 2) { 
     for (j in 1: 2) { 
     pos1[i] <- sapply(strsplit(substr(text, 0,char1[i]-1),"\\s"),length)+1 
     pos2[j] <- sapply(strsplit(substr(text, 0,char2[j]-1),"\\s"),length)+1 
     dist <- pos2[i] - pos1[j] 

     a <- ifelse(pos1[i]>0 & pos2[j]>0 & dist>0 & dist<=6,1,0) 
     if (a==1) break 
     return(a) 
     } 

    } 
} 

text <- "phone rang a b c d e f z y z phone rang but no answer" 
b <- sapply(text, FUN=function(str) phrasedis(str,"phone rang" , "no answer",6)) 

它应该做的是返回1,如果手机之间的距离铃响了,没有答案是小于6个字,否则返回0 非常感谢您的帮助。

+0

嗨里斯,谢谢你,但除去休息后,它仍然没有给我任何结果。 – baver

+0

这是因为你的函数在你想改变它们之前没有定义对象'pos1'和'pos2'。在你的循环之前加入'pos1 < - pos2 < - c(0,0)',并将return语句移到函数的绝对末尾。 –

+0

嗨,对不起,它确实会返回1,但是当我将文本更改为“电话铃响了电话时,它仍然返回1”。看起来无论文字是什么,它都返回1。 – baver

回答

4

你的函数的逻辑错误。

首先,您将return()语句放入循环中,所以循环由于return()语句而始终在第一次迭代中停止。

然后,你不创建矢量pos1pos2,所以你的功能甚至不能工作。您不抱怨错误的唯一原因是您可能在全球环境中有pos1pos2

但是,即使将return语句放在应该去的地方(最后!)并创建长度为2的pos1和pos2向量,由于循环错误,您的函数无法工作。

您循环超过1和2,除非在string中有phrase1phrase2两个确切的匹配,否则根本没有意义。由于这一点,事实上phrase2只有1个匹配,所以当j==2substr(text, 0, char2[j] -1)的结果是NA,其精确长度为1,因此pos2 [j]变为2.同时pos1 [i]仍然是1,满足您的情况,因此1返回。

这是你如何能做到这一点:

phrasedis <- function(string, phrase1, phrase2,n) { 
    char1 <- gregexpr(phrase1,string)[[1]] 
    char2 <- gregexpr(phrase2,string)[[1]] 

    # -1 is returned if no match was found for either phrase 
    if(any(c(char1,char2) == -1)){ 
    return(0) 
    } 
    # Calculate the end positions of the words 
    end1 <- char1 + attr(char1, "match.length") 

    #set a to 0 
    a <- 0 
    # loop over all matches in char1 
    for(i in seq_along(char1)){ 
    # Find the closest match for phrase 2 
    thepos <- which.min(abs(char2 - end1[i])) 
    # get all words in between. 
    # Don't forget to trim white spaces before and after 
    inbetween <- trimws(substring(string, end1[i], char2[thepos]-1)) 
    inbetween <- strsplit(inbetween,"\\s")[[1]] 
    if(length(inbetween) <= n){ 
     a <- 1 
     break 
    } 

    } 
    return(a) 
} 

这是它如何工作的:

> text <- "phone rang a b cd phone rang d e f g h i no answer" 

> phrasedis(text,"phone rang" , "no answer",6) 
[1] 1 

> text <- " There is nothing in this text" 

> phrasedis(text,"phone rang" , "no answer",6) 
[1] 0 

> text <- "No answer but the phone rang" 

> phrasedis(text,"phone rang" , "no answer",6) 
[1] 0 
+0

非常感谢您的详细解答。我是R新手,这是我的第一个功能,你的回答真的很有帮助。 – baver