0

假設我有以下類似的數據結構,其中DOC_ID是文件標識符,text_id是唯一的文本/版本標識和文字是一個字符串:有條件的循環在R不識別條件語句?

df <- cbind(doc_id=as.numeric(c(1, 1, 2, 2, 3, 4, 4, 4, 5, 6)), 
       text_id=as.numeric(c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)), 
        text=as.character(c("string1", "str2ing", "3string", 
             "string6", "s7ring", "string8", 
             "string9", "string10"))) 

什麼我試圖在循環做結構是做字符串編輯距離比較,但只針對同一文檔的不同版本。簡而言之,我想查找匹配的doc_ids,並且僅比較同一文檔的不同版本(text_ids)。

#Results matrix 
result <- matrix(ncol=10, nrow=10) 

#Loop 
i=1 
for (j in 1:length(df[,2])) { 
    for (i in 1:length(df[,2])) { 
#Conditional Statements 
    if(df[i,1]==df[j,1]){ 
     result[i,j]<-levenshteinDist(df[j,3], df[i,3])} 
    else(result[i,j]<-"Not Compared") 
    } 
    print(result[i,j]) 
    flush.console() 
} 

返回:

[1] "Not Compared" 
[1] "Not Compared" 
[1] "Not Compared" 
[1] "Not Compared" 
[1] "Not Compared" 
[1] "Not Compared" 
[1] "Not Compared" 
[1] "Not Compared" 
[1] "Not Compared" 
[1] "0" 

levenshteinDist()功能可在RecordLinkage包中找到,但有類似的功能也被捆綁在utils封裝adist()

我的問題是爲什麼我的第一個條件語句(if)被忽略,只有其他部分被返回?

任何關於編碼或處理時間效率收益的進一步建議將不勝感激。

+0

您是否檢查過結果矩陣,它看起來像是在工作,您在這裏看到的輸出僅適用於最後一行(或列)..查看您的i,j排序。 (df [i,1] == df [j,1])'你打算做什麼'if(df [i,1] == df [j,2]) '? – Ananta

+0

我只想在不同版本的「相同」文檔(相當於doc_ids但不同的text_ids)之間進行比較(字符串距離)......所以不需要。但是你提出的建議是改變輸出結構是正確的,按照@Maiasaura的原始建議。 –

回答

0

您輸出不正確。運行此版本並查看正在發生的比較。一旦你確信一切工作正常,請將message()評論一下。

library(RecordLinkage) 

df <- structure(c("1", "1", "2", "2", "3", "4", "4", "4", "5", "6", 
"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "string1", 
"str2ing", "3string", "string6", "s7ring", "string8", "string9", 
"string10", "string1", "str2ing"), .Dim = c(10L, 3L), .Dimnames = list(
    NULL, c("doc_id", "text_id", "text"))) 

result <- matrix(ncol = 10, nrow = 10) 
# nrow() and ncol() are more elegant ways of getting row/column counts. 
for(j in 1:nrow(df)) { 
    for(i in 1:nrow(df)) { 
     message(sprintf("comparing i=%s (%s), j=%s (%s)\n", j, df[i, 1], i, df[j, 1])) 
     if(identical(df[i, 1], df[j, 1])) { 
      result[i, j] <- levenshteinDist(df[j, 3], df[i, 3]) 
     } else { 
      result[i, j] <- "Not Compared" 
     } 
      # printing inside the inner for loop 
     print(result[i, j]) 
    } 

} 
+0

感謝您提供建議印刷在每個比較。 此外,就推廣我的最終目標是什麼而言,相同的功能更有意義。 –

0

對於初學者來說,如果我理解你的目標if-statement應該是if (df[i,1]==df[j,2]),這樣你就可以比較兩列的值。

這裏的問題不是你的條件被忽略,而是你要錯誤地輸出你的結果。 result這裏是由一個10x10矩陣組成的,但是您只在j的迭代循環內打印result[i,j]。我認爲代碼應該看起來更像是這樣的:

for (i in 1:length(df[,2])) { 
    for (j in 1:length(df[,2])) { 

     if(df[i,1]==df[j,2]) { 
      result[i,j]<-adist(df[j,3], df[i,3]) 
     } else { 
      (result[i,j]<-"Not Compared") 
     } 
    } 
} 

這將生成結果的矩陣,然後你可以根據你的願望查看全部100個比較的結果。

+0

我只想在「相同」文檔的不同版本(等效doc_ids但不同text_ids)之間進行比較(字符串距離)。 –