Запишите результаты цикла for мер расстояния в матричной форме в R

Предположим, у меня есть что-то вроде следующего вектора:

text <- as.character(c("string1", "str2ing", "3string", "stringFOUR", "5tring", "string6", "s7ring", "string8", "string9", "string10"))

Я хочу выполнить цикл, который попарно сравнивает расстояние редактирования всех возможных комбинаций этих строк (например, строка 1 и строка 2, строка 1 и строка 3 и т. д.). Вывод должен быть в матричной форме со строками, равными количеству строк, и столбцами, равными количеству строк.

У меня есть следующий код ниже:

#Matrix of pair-wise combinations
m <- expand.grid(text,text)

#Define number of strings
n <- c(1:10)

#Begin loop; "method='osa'" in stringdist is default
for (i in 1:10) {
  n[i] <- stringdist(m[i,1], m[i,2], method="osa")
  write.csv(data.frame(distance=n[i]),file="/File/Path/output.csv",append=TRUE)
  print(n[i])
  flush.console()
}

Функция stringdist() из пакета stringdist{}, но эта функция также включена в базовый пакет utils как adist()

Мой вопрос: почему мой цикл не записывает результаты в виде матрицы и как мне остановить цикл от перезаписи каждого отдельного расчета расстояния (т. е. сохранить все результаты в матричной форме)?


person DV Hughes    schedule 05.08.2013    source источник
comment
+1 за хороший, чистый воспроизводимый пример.   -  person Ricardo Saporta    schedule 06.08.2013


Ответы (1)


Я бы предложил использовать stringdistmatrix вместо stringdist (особенно если вы используете expand.grid)

 res <- stringdistmatrix(text, text)
 dimnames(res) <- list(text, text)  
 write.csv(res, "file.csv")

Что касается вашего конкретного вопроса: "Мой вопрос: почему мой цикл не записывает результаты в виде матрицы"
Непонятно, почему вы ожидаете, что на выходе будет матрица? Вы вычисляете элемент за раз, сохраняете его в вектор, а затем записываете этот вектор на диск.

Кроме того, вы должны знать, что аргументы write.csv по большей части бесполезны (я полагаю, они здесь просто для того, чтобы напомнить пользователю, что такое значения по умолчанию). Вместо этого используйте write.table

Если вы хотите сделать это итеративно, я бы сделал следующее:

# Column names, outputted only one time
write.table(rbind(names(data.frame(i=1, distance=n[1])))
            ,file="~/Desktop/output.csv",append=FALSE   # <~~ Don't append for first run.
             , sep=",", col.names=FALSE, row.names=FALSE)

for (i in 1:10) {
  n[[i]] <- stringdist(m[i,1], m[i,2], method="osa")
  write.table(data.frame(i=i, distance=n[i]),file="~/Desktop/output.csv"
              ,append=TRUE, sep=",", col.names=FALSE, row.names=FALSE)
  print(n[[i]])
  flush.console()
}
person Ricardo Saporta    schedule 05.08.2013
comment
R Сеансы прерываются из-за больших строк (из-за проблем с ОЗУ/памятью). Поэтому я использую матричную нотацию, stringdist(), а не stringdistmatrix(), и периодически сохраняю и печатаю результаты на протяжении выполнения цикла. - person DV Hughes; 06.08.2013
comment
@DVHughes это имеет смысл. Попробуйте вместо этого использовать write.table (см. редактирование) - person Ricardo Saporta; 06.08.2013