0
votes

I have four different data frames. They are named "data_QB", "data_WR", "data_RB", and "data_TE". I want to get the interquartile range of a common variable in each of them ("ppr") and assign these values to "iqr_QB", "iqr_WR", "iqr_RB", and "iqr_TE", respectively. I'd like to do this without having to repeat the code four times.

I tried

clist = c("QB", "WR", "RB", "TE")
for (i in clist) {
  assign(paste0("iqr_", i)), IQR(assign(paste0("data_", i)$ppr)))
}

but I got the error message:

Error: $ operator is invalid for atomic vectors

Does anyone know how I could do this? Any help would be greatly appreciated!

2
put all the data frames in a list and loop over it. Something like lapply(list(your_dataframes), function(i)IQR(i$your_var)) - Sotos

2 Answers

0
votes

I would suggest next approach. You have your dataframes in environment so you can use sapply() inside the loop using their names and then eval() to create the new variable. In the case of this example, we will compute IQR for Sepal.Length using as dataframes all groups from Species in iris dataset. Next code:

#Dummy data
data("iris")
#Create example data
List <- split(iris,iris$Species)
names(List) <- paste0('data_',names(List))
list2env(List,envir = .GlobalEnv)

We define the names:

#Now set a vector
clist = c("data_setosa", "data_versicolor", "data_virginica")

We create the loop using eval() and bquote() functions:

#Loop
for(x in sapply(clist,as.name)) {
  eval(bquote(.(x)[[paste0('iqr_',x)]] <- IQR(.(x)[['Sepal.Length']])))
}

This will produce a new variable in all of your dataframes. Here one example (Some rows):

data_versicolor

    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species iqr_data_versicolor
51           7.0         3.2          4.7         1.4 versicolor                 0.7
52           6.4         3.2          4.5         1.5 versicolor                 0.7
53           6.9         3.1          4.9         1.5 versicolor                 0.7
54           5.5         2.3          4.0         1.3 versicolor                 0.7
55           6.5         2.8          4.6         1.5 versicolor                 0.7
56           5.7         2.8          4.5         1.3 versicolor                 0.7
57           6.3         3.3          4.7         1.6 versicolor                 0.7
58           4.9         2.4          3.3         1.0 versicolor                 0.7
0
votes

Expanding @Sotos' comment into an answer :

  1. Get the data in a list using mget
  2. Use lapply to iterate over the list and calculate IQR for the ppr variables.
  3. Output of step 2 is a list, give it appropriate name based on your requirement.
  4. Use list2env to get vectors in your global environment.
clist = c("QB", "WR", "RB", "TE")
new_data <- lapply(mget(paste0('data_', clist)), function(x) IQR(x$ppr))
names(new_data) <- paste0('iqr_', clist)
list2env(new_data, .GlobalEnv)

You can avoid step 3 and 4 if you decide to keep data in a list and not create separate vectors out of it. Lists are easier to manage and do not populate global environment with lot of objects.