Chris Fenton
Chris Fenton

Reputation: 61

Using apply family of functions to replace nested for loop in R

I wrote a function that takes 3 arguments:

download_data <- function(team, year, df) {
    ...
}

I have two character vectors that I want to use to provide the first and second argument respectively to the above function, so that each combination of the vectors is called once:

nfl_teams <- c("bills", "dolphins", "jets", "patriots")

years <- c("2002", "2003", "2004", "2005")

I can do so fairly easily using a nested for loop:

for (i in 1:4) {
  for ( j in 1:4) {
    salary_data <- download_data(nfl_teams[i], years[j], salary_data)
  }
}

However, it seems that this an "un-R" way to accomplish this, and it would be better to use one of the apply functions. However, after reading through all of them and trying them out, I was unable to accomplish this seemingly simple task.

It seems like maybe this would be a matrix, thus apply would work?

Upvotes: 6

Views: 8274

Answers (3)

SabDeM
SabDeM

Reputation: 7200

Another way could be by coercing an object to a list and by doing so avoiding a nested apply family function.

 unlist(lapply(as.list(nfl_teams), function(x) dummy(x, years) ))
 [1] "bills 2002"    "bills 2003"    "bills 2004"    "bills 2005"   
 [5] "dolphins 2002" "dolphins 2003" "dolphins 2004" "dolphins 2005"
 [9] "jets 2002"     "jets 2003"     "jets 2004"     "jets 2005"    
[13] "patriots 2002" "patriots 2003" "patriots 2004" "patriots 2005"

Upvotes: 0

Benjamin
Benjamin

Reputation: 17279

If you're download_data function is using nfl_teams and years to construct URLs from which to pull data, I would recommend an approach like this:

URL <- expand.grid(nfl_teams = c("bills", "dolphins", "jets", "patriots"),
    years = c("2002", "2003", "2004", "2005"),
    stringsAsFactors = FALSE)
URL$url <- paste0(...) # build your url string here

salary_data <- lapply(URL$url, download_data)
salary_data <- do.call("rbind", salary_data)

This approach assumes that you're binding each iteration of download_data into the existing salary_data. It's the repetitive binding that I would want to get rid of, if possible.

Upvotes: 2

Rorschach
Rorschach

Reputation: 32456

You can use the apply functions just like loops, except with different syntax

dummy <- function(x, y) paste(x, y)
sapply(1:4, function(i) sapply(1:4, function(j) dummy(nfl_teams[i], years[j])))

Upvotes: 10

Related Questions