Função eficiente (memória-sábia) para cálculos de matriz de distância repetidos E chunking de matrizes de distância extra grande
Gostaria de saber se alguém poderia dar uma olhada no código a seguir e no exemplo mínimo e sugerir melhorias - em particular, em relação à eficiência do código ao trabalhar com conjuntos de dados realmente grandes.
A função pega um data.frame e o divide por uma variável de agrupamento (fator) e, em seguida, calcula a matriz de distância para todas as linhas em cada grupo.
Eu não preciso manter as matrizes de distância - apenas algumas estatísticas, ou seja, a média, o histograma ..., então elas podem ser descartadas.
Eu não sei muito sobre alocação de memória e coisas do tipo e estou imaginando qual seria a melhor maneira de fazer isso, já que eu estarei trabalhando com 10.000 - 100.000 de casos por grupo. Qualquer pensamento será muito apreciado!
Além disso, qual seria a maneira menos dolorosa de incluir bigmemory ou algum outro grande pacote de manipulação de dados na função, como é o caso de eu ter sérios problemas de memória?
FactorDistances <- function(df) {
# df is the data frame where the first column is the grouping variable.
# find names and number of groups in df (in the example there are three:(2,3,4)
factor.names <- unique(df[1])
n.factors <-length(unique(df$factor))
# split df by factor into list - each subset dataframe is one list element
df.l<-list()
for (f in 1:n.factors) {df.l[[f]]<-df[which(df$factor==factor.names[f,]),]}
# use lapply to go through list and calculate distance matrix for each group
# this results in a new list where each element is a distance matrix
distances <- lapply (df.l, function(x) dist(x[,2:length(x)], method="minkowski", p=2))
# again use lapply to get the mean distance for each group
means <- lapply (distances, mean)
rm(distances)
gc()
return(means)
}
df <- data.frame(cbind(factor=rep(2:4,2:4), rnorm(9), rnorm(9)))
FactorDistances(df)
# The result are three average euclidean distances between all pairs in each group
# If a group has only one member, the value is NaN
Editar: editei o título para refletir o problema que eu publiquei como resposta.