I’d like to generate some simple calculations for each combination of two factor variables and store the results in a data frame. Here are the data:
df <- data.frame(SPECIES = as.factor(c(rep("SWAN",10), rep("DUCK",4), rep("GOOS",12),
rep("PASS",9), rep("FALC",10))),
DRAINAGE = as.factor(c(rep(c("Central", "Upper", "West"),15))),
CATCH_QTY = c(1,1,2,5,6,1,2,1,1,1,1,1,3,1,1,2,1,1,2,2,
rep(1,25)),
TAGGED = c(rep("T",6),NA,"T","T",NA,rep("T",10),NA,NA,
rep("T",9),NA,"T","T","T","T",NA,rep("T",7),NA),
RECAP = c(rep(NA,6),"RC",NA,NA,"RC",rep(NA,10),"RC","RC",
rep(NA,9),"RC",NA,NA,NA,NA,"RC",rep(NA,7),"RC"))
And here is the function:
myfunction <- function(dat, yr, spp, drain){
dat <- dat %>% filter(SPECIES == spp, DRAINAGE == drain)
estimatea <<-
dat %>%
summarise(NumCaught = sum(CATCH_QTY, na.rm = T),
NewTags = sum(!is.na(TAGGED)),
Recaps = sum(!is.na(RECAP)),
TotTags = sum(NewTags+Recaps))
dataTest1 <- cbind(yr, spp, drain, estimatea$NumCaught, estimatea$NewTags,
estimatea$Recaps, estimatea$TotTags)
}
I’ve mostly been experimenting with nested for loops and have been struggling to store the output in a dataframe given that the variables over which I am iterating are factors, rather than numeric, therefore a lot of the existing answers on stack exchange aren’t relevant. The answer for iterating over factors here
does not show how to store the output.
Some examples of my attempts:
out <- list()
for (i in seq_along(levels(df$SPECIES))) {
for (j in seq_along(levels(df$DRAINAGE))) {
out[i,j] <- myfunction(df, "2023", i, j)
}
}
Error in out[i, j] <- myfunction(df, "2023", i, j) :
incorrect number of subscripts on matrix
for (i in seq_along(levels(df$SPECIES))) {
for (j in seq_along(levels(df$DRAINAGE))) {
out[i+1,j+1] <- myfunction(df, "2023", i, j)
}
}
Error in out[i, j] <- myfunction(df, "2023", i, j) :
incorrect number of subscripts on matrix
I’ve also considered some non-for loop options, e.g.,
combos <- expand.grid(df$SPECIES, df$DRAINAGE) %>% distinct() %>%
drop_na() %>% rename(spp = Var1, drain = Var2)
test <- myfunction(df, "2023", combos$spp, combos$drain) #generates incorrect results
sapply(combos$spp, function(x) mapply(myfunction,x,combos$drain))
apply(combos, 2, FUN = myfunction)
Error in UseMethod("filter") :
no applicable method for 'filter' applied to an object of class "character"
Ideally, the output dataframe would look something like this:
desired_out <- data.frame(yr = rep("2023",3),
spp = c("DUCK", "DUCK", "GOOS"),
drain = c("West", "Central", "Upper"),
V4 = c(1,3,4),
V5 = c(1,1,3),
v6 = c(0,0,1),
V7 = c(1,1,4))
payne is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.