Wydajna (pod względem pamięci) funkcja do obliczeń macierzy wielokrotnych odległości ORAZ porcjowania bardzo dużych macierzy odległości
Zastanawiam się, czy ktoś mógłby przyjrzeć się poniższemu kodowi i minimalnemu przykładowi i zasugerować ulepszenia - w szczególności dotyczące wydajności kodu podczas pracy z naprawdę dużymi zestawami danych.
Funkcja pobiera ramkę danych i dzieli ją na zmienną grupującą (czynnik), a następnie oblicza macierz odległości dla wszystkich wierszy w każdej grupie.
Nie muszę utrzymywać macierzy odległości - tylko niektóre statystyki, tj. Średnią, histogram .., a następnie można je odrzucić.
Nie wiem zbyt wiele o alokacji pamięci i tym podobnych, i zastanawiam się, jaki byłby najlepszy sposób, aby to zrobić, ponieważ będę pracować z 10.000 - 100.000 przypadków na grupę. Wszelkie myśli będą bardzo mile widziane!
Co byłoby najmniej bolesnym sposobem włączenia funkcji bigmemory lub innego dużego pakietu do obsługi danych do funkcji, jak w przypadku poważnych problemów z pamięcią?
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
Edytuj: edytowałem tytuł, aby odzwierciedlić problem z kawałkami, który zamieściłem jako odpowiedź.