我正在尝试生成文档的术语频率矩阵,然后在该矩阵中查找给定查询中某个单词的频率。最后,我想对查询中单词的出现频率求和。但是,我正在处理错误消息:feature [i]中的错误
一般而言,我没有太多的编码经验,这是我第一次使用R,因此我很难解决此错误。我认为它与空值有关。我已经尝试避免使用apply函数嵌套嵌套的for循环,因为我认为这可能会有所帮助(虽然不确定),但是我不太了解如何将for循环转换为apply函数。
n <- length(queries)
feature <- vector(length=n)
for(i in 1:n){
query <- queries[i]
documentcorpus <- c(docs[i])
tdm <- TermDocumentMatrix(tm_corpus) #creates the term frequency matrix per document
m <- sapply(strsplit(query, " "), length) #length of the query in words
totalfreq <- list(0) #initialize list
freq_counter <- rowSums(as.matrix(tdm)) #counts the occurrence of a given word in the tdm matrix
for(j in 1:m){
freq <- freq_counter[word(query,j)] #finds frequency of each word in the given query, in the term frequency matrix
totalfreq[[j]] <- freq #adds this frequency to position j in the list
}
x <- reduce(totalfreq,'+') #sums all the numbers in the list
feature[i] <- x #adds this number to feature list
feature
}
}
这取决于您的需求,但最重要的是您需要添加一些if
语句。如何使用它取决于是否要保留向量的默认值。在您的代码中,虽然feature
作为逻辑矢量开始,但是一旦您用数字覆盖其第一个值,它就有可能被强制为integer
或numeric
。在这种情况下,矢量所有位置的默认值为0
(如果为整数,则为0L
)。这将影响您对如何使用if
语句的决定。
if (length(x)) feature[i] <- x
仅当i
对象具有长度(等于feature
)时,才会尝试覆盖x
的第if (length(x) > 0)
个值。在这种情况下,由于向量中的默认值将为零,因此这意味着完成操作后,您将无法区分已知为0
的元素和找不到任何内容的元素。
替代方法(以及我的偏好/推荐):
feature[i] <- if (length(x)) x else NA
在这种情况下,完成后,您可以清楚地区分已知零(0
)和不确定/未知值(NA
)。在该向量上进行数学运算时,可能需要/需要na.rm=TRUE
...,但这全部取决于您的使用。
顺便说一句,正如MartinGal所指出的,您对reduce(totalfreq, '+')
的使用有点缺陷:'x'
可能不被(不是?)识别为已知函数。第一个解决方法是在函数周围使用反引号,因此
totalfreq <- 5:7
reduce(totalfreq, '+')
# NULL
reduce(totalfreq, `+`)
# [1] 18
sum(totalfreq)
# [1] 18
最后一种是首选方法。为什么?例如,对于一个长度为4的向量,它将取前两个并将其相加,然后将结果加到第三个,然后将结果并加到第四个。三个操作。当您有100个元素时,它将进行99个单独的添加。 sum
会执行一次,这确实会(渐近地)影响性能。
但是,如果totalfreq
代替为list
,则这会稍有变化:
totalfreq <- as.list(5:7)
reduce(totalfreq, `+`)
# [1] 18
sum(totalfreq)
# Error in sum(totalfreq) : invalid 'type' (list) of argument
# x
sum(unlist(totalfreq))
# [1] 18
reduce
代码仍然有效,并且sum
本身失败,但是我们可以先unlist
列表,有效地创建向量,然后在其上调用sum
。渐近地快得多。也许更清晰,更具声明性。
(我假设purrr::reduce
,顺便说一句...]