2017-04-12 213 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