Da Sie die Tags dplyr
und purrr
hinzufügen, nehme ich an, dass Sie an einer tidyverse
Lösung interessiert sind. Im Folgenden werde ich eine Lösung auf Basis der tidyverse
demonstrieren.
Zunächst ist Ihre range_stats
problematisch. Deshalb haben Sie die Fehlermeldung erhalten. Die weighted.mean
erwartet einen Vektor für die beiden x
und w
Argument. Wenn rangedf
jedoch eine tibble
ist, wird die Art und Weise, wie Sie die tibble
tibble
wie rangedf[,lat]
noch eine einspaltige tibble
zurückgeben. Ein besserer Weg ist, pull
aus dem dplyr
Paket zu verwenden.
library(tidyverse)
range_stats <- function(rangedf, lat, lon, weighting, na.rm=T){
cent_lat <- weighted.mean(x = rangedf %>% pull(lat),
w = rangedf %>% pull(weighting), na.rm=T)
cent_lon <- weighted.mean(x = rangedf %>% pull(lon),
w = rangedf %>% pull(weighting), na.rm=T)
out <- data.frame(cent_lat, cent_lon)
return(out)
}
Als nächstes wird die Art und Weise Sie den Datenrahmen erstellt ist OK, aber data.table
ist vom data.table
Paket und Sie werden ein data.table
, kein tibble
erstellen. Ich dachte, Sie wollen einen Ansatz von tidyverse
verwenden, also änderte ich data.table
zu data_frame
wie folgt.
LATITUDE <- c(27.91977, 21.29066, 26.06340, 28.38918, 25.97517, 27.96313)
LONGITUDE <- c(-175.8617, -157.8645, -173.9593, -178.3571, -173.9679, -175.7837)
BIOMASS <- c(4.3540488, 0.2406332, 0.2406332, 2.1419699, 0.3451426, 1.0946017)
SPECIES <- c('Abudefduf abdominalis','Abudefduf abdominalis','Abudefduf abdominalis','Chaetodon lunulatus','Chaetodon lunulatus','Chaetodon lunulatus')
YEAR <- c('2005', '2005', '2014', '2009', '2009', '2015')
testdf <- data_frame(LATITUDE, LONGITUDE, BIOMASS, SPECIES, YEAR)
Nun, Sie sagten, Sie die range_stats
Funktion zu jeder Kombination von SPECIES
und YEAR
anwenden möchten. Ein Ansatz besteht darin, den Datenrahmen in eine Liste von Datenrahmen aufzuteilen und die Familienfunktion lapply
zu verwenden. Aber hier möchte ich Ihnen zeigen, wie man die map
Familienfunktion verwendet, um diese Aufgabe zu erfüllen, da map
aus dem purrr
Paket ist, das Teil der tidyverse
ist.
Wir können zuerst eine Gruppe Indizes basierend auf SPECIES
und YEAR
erstellen.
testdf2 <- testdf %>%
mutate(Group = group_indices(., SPECIES, YEAR))
testdf2
# A tibble: 6 x 6
LATITUDE LONGITUDE BIOMASS SPECIES YEAR Group
<dbl> <dbl> <dbl> <chr> <chr> <int>
1 27.91977 -175.8617 4.3540488 Abudefduf abdominalis 2005 1
2 21.29066 -157.8645 0.2406332 Abudefduf abdominalis 2005 1
3 26.06340 -173.9593 0.2406332 Abudefduf abdominalis 2014 2
4 28.38918 -178.3571 2.1419699 Chaetodon lunulatus 2009 3
5 25.97517 -173.9679 0.3451426 Chaetodon lunulatus 2009 3
6 27.96313 -175.7837 1.0946017 Chaetodon lunulatus 2015 4
Wie Sie sehen können, ist Group
eine neue Spalte die Indexnummer zeigt. Jetzt können wir den Datenrahmen basierend auf Group
aufteilen und dann map_dfr
verwenden, um die range_stats
Funktion anzuwenden.
testresult <- testdf2 %>%
split(.$Group) %>%
map_dfr(range_stats, lat = "LATITUDE",lon = "LONGITUDE",
weighting = "BIOMASS", na.rm = TRUE, .id = "Group")
testresult
Group cent_lat cent_lon
1 1 27.57259 -174.9191
2 2 26.06340 -173.9593
3 3 28.05418 -177.7480
4 4 27.96313 -175.7837
Hinweis, dass map_dfr
kann die automatische bind der Ausgabeliste von Datenrahmen zu einem einzelnen Datenrahmen. .id = "Group"
bedeutet, dass wir basierend auf dem Namen des Listenelements eine Spalte namens Group
erstellen möchten.
Ich habe den Prozess in zwei Schritte getrennt, aber natürlich können sie alle in einer Pipeline wie folgt sein.
testresult <- testdf %>%
mutate(Group = group_indices(., SPECIES, YEAR)) %>%
split(.$Group) %>%
map_dfr(range_stats, lat = "LATITUDE",lon = "LONGITUDE",
weighting = "BIOMASS", na.rm = TRUE, .id = "Group")
Wenn Sie möchten, testresult
mit testdf
mit left_join
zusammengeführt werden, aber ich werde hier aufhören als testresult
wahrscheinlich ist bereits die gewünschte Ausgabe, die Sie wollen. Ich hoffe das hilft.
Perfekte Lösung, danke! Ich habe es genau implementiert, außer "mutate" (Group = group_indices (., SPECIES, YEAR)) ', habe ich einen aussagekräftigen Spaltennamen verwendet, so dass der Bezeichner in der Ausgabe df sinnvoll ist:' muate (GROUPID = paste (YEAR, Spezies)) '. – AFH
@AFH Schöne Möglichkeit, aussagekräftige Gruppenname oder ID zu erstellen. Danke für das Teilen. – www