0

I want to loop through the names of a character variable of this type:

names_list <- c("USA", "VEN", "CHE")

Then, I create the following loop:

for (i in names_list) {
  set.seed(123333)
  test <- predictors_no_NA %>%
    filter(ISO3_baci != i)

predictions <- predict(rf150, test, predict.all=TRUE, type = "prob")
  predictions <- as.data.frame(predictions[1])
  predictions <- predictions %>%
    select(aggregate.1) %>%
    rename(predictions[i] = aggregate.1)    % HERE APPEARS THE 1st PROBLEM

  test_RF_[i] <- cbind(test, predictions)   % HERE APPEARS THE 2nd PROBLEM
}

Note that variable "rf150" is created inside the loop without any problem (don't show the code here).

The problem arises when I want to add the string element of the loop (e.g. "USA") to my created name "predictions_[i]" or "test_RF_[i]", so that I can get a variable that is called: "predictions_USA" or "test_RF_USA" as well as "predictions_VEN" or "test_RF_VEN" and "predictions_CHE" or "test_RF_CHE"

Any clue?

Regards

vog
  • 770
  • 5
  • 11
  • Have you try with assign + pasteo ?? – Santiago I. Hurtado Jun 08 '20 at 11:06
  • I have tried it but either I don't implement I correctly or it really does not work inside a dplyr framework – vog Jun 08 '20 at 11:18
  • I the second problem it should work, I think. In the first maybe using {{ }} – Santiago I. Hurtado Jun 08 '20 at 11:22
  • 1
    Your problem is that `deplyr`, along with other `tidyverse` packages, uses non-standard evaluation. One solution is to use `{{`` and `}}` as suggested by @SantiagoI.Hurtado. However, the structure I think you are trying to use is not [tidy](https://cran.r-project.org/web/packages/tidyr/vignettes/tidy-data.html). I strongly suggest adapting your workflow to make it tidy. A little effort now will save you much pain later on. – Limey Jun 08 '20 at 11:35
  • Thanks to both @SantiagoI.Hurtado and Limey. Helpful recommendations! – vog Jun 08 '20 at 21:50

1 Answers1

1

Firstly, for the dynamic renaming in your loop, the following snippet should help (I've taken the freedom to alter it a little:

library(tibble) # if you want to use as_tibble() rather than as.data.frame()
library(dplyr)

predictions <- predict(rf150, test, predict.all=TRUE, type = "prob") %>%
    .[1] %>%
    as_tibble() %>%
    select(!!paste0('predictions_',i) := aggregate.1)

There's a very helpful and detailed answer on the topic of dynamic variable names in dplyr over here.

Alternative solution, since you had already selected only the one column that you wanted to colbind:

predictions  <- [...] %>%
    select(aggregate.1) %>%
    `colnames<-`(paste0('predictions_',i))

Secondly, to assign the data frame to a variable, as commented by Santiago above, assign should get you there:

assign(
    paste0('test_RF_',i),
    cbind(test, predictions),
    envir=globalenv()
)
alex_jwb90
  • 1,663
  • 1
  • 11
  • 20