R中的条件for循环不识别条件语句?

时间:2013-10-31 23:52:05

标签: r for-loop conditional-statements string-matching levenshtein-distance

假设我有以下类似的数据结构,其中doc_id是文档标识符,text_id是唯一的文本/版本标识符,text是字符串:

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)被忽略,只返回了else部分?

有关编码或处理时间效率收益的任何进一步建议将不胜感激。

2 个答案:

答案 0 :(得分:0)

首先,如果我了解您的目标if-statement应该阅读if (df[i,1]==df[j,2]),那么您要对两列的值进行比较。

这里的问题不是你的条件被忽略了,而是你要错误地输出你的结果。 result此处由10x10矩阵组成,但您只在循环中打印result[i,j],迭代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个比较的结果。

答案 1 :(得分: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])
    }

}