for-Loop in R (10 Examples) | Writing, Running & Using Loops in RStudio

 

This post explains how to write and run for-loops in the R programming language.

The post will contain these content blocks:

Before we dive into the examples, let’s start with a quick theoretical introduction to for-loops…

 

Theoretical Workflow of for-Loops

I’ll first explain the workflow of for-loops. Have a look at the following graphic, it illustrates how for-loops work in theory:

 

for loop flowchart in R

 

At the beginning of each for-loop is a head that defines a collection of objects such as the elements of a vector or a list.

The head is followed by a code block (i.e. the body of our loop). In this block we can execute basically any R syntax we want.

Afterwards, the for-loop checks whether it reached the last object of the collection specified in the head of the loop. If this is the case, the for-loop is stopped. If this is not the case, the code block within the for-loop is repeated.

In the following, I’ll show you ten examples for the application of for-loops in R. So keep on reading!

 

Example 1: Loop Through Vector in R (Basics)

In this Example, I’ll illustrate how to use for-loops to loop over a vector.

In the following R code, we are specifying within the head of the for-loop that we want to run through a vector containing ten elements from the first element (i.e. 1) to the last element (i.e. 10).

Within the body of the for-loop we are then creating an output called x1, which contains the index of our loop to the power of 2. We are printing the result of our code block in each iteration to the RStudio console.

Let’s have a look at the R syntax and its output:

for(i in 1:10) {                                           # Head of for-loop
 
  x1 <- i^2                                                # Code block
  print(x1)                                                # Print results
}
# [1] 1
# [1] 4
# [1] 9
# [1] 16
# [1] 25
# [1] 36
# [1] 49
# [1] 64
# [1] 81
# [1] 100

As you can see, the previous R code returned ten values, i.e. one value for each iteration.

Please have a look at this tutorial in case you want to learn more about for-loops and vectors in R.

 

Example 2: Looping Over Character Vectors

It is very important to understand that for-loops in R do not iterate over regular sequences, but over a collection of objects. For that reason, we are able to loop through vectors of character strings.

Let’s do an example in R! First, we have to create a character vector:

x2 <- c("Max", "Tina", "Lindsey", "Anton", "Sharon")       # Create character vector

Now, we can loop over the elements of this character vector as shown below:

for(i in x2) {                                             # Loop over character vector
 
  print(paste("The name", i, "consists of", nchar(i), "characters."))
}
# [1] "The name Max consists of 3 characters."
# [1] "The name Tina consists of 4 characters."
# [1] "The name Lindsey consists of 7 characters."
# [1] "The name Anton consists of 5 characters."
# [1] "The name Sharon consists of 6 characters."

If you want to learn more about loops and character vectors, you can have a look here.

 

Example 3: Store for-Loop Results in Vector by Appending

This Example shows how to concatenate the output of each for-loop iteration to a vector. For this task, we first have to create an empty vector:

x3 <- numeric()                                            # Create empty data object

Now, we can use the for-statement to create a vector of output values:

for(i in 1:10) {                                           # Head of for-loop
 
  x3 <- c(x3, i^2)                                         # Code block
}

Let’s print the results:

x3                                                         # Print results
# [1]   1   4   9  16  25  36  49  64  81 100

The resulting values are exactly the same as in the first example. However, this time we have saved the results in a vector object. You can learn more on this topic here.

 

Example 4: Nested for-Loop in R

for-loops are often used in nested loops. In Example 4, I’ll show how to nest a for-loop into another for-loop.

Let’s first create another empty vector (as in Example 3):

x4 <- character()                                          # Create empty data object

Now, we can use the following nested for-loop to create a vector were each vector element contains two (different) letters of the alphabet:

for(i in 1:5) {                                            # Head of first for-loop
 
  for(j in 1:3) {                                          # Head of nested for-loop
 
    x4 <- c(x4, paste(LETTERS[i], letters[j], sep = "_"))  # Code block
  }
}

Let’s show the result:

x4                                                         # Print results
# "A_a" "A_b" "A_c" "B_a" "B_b" "B_c" "C_a" "C_b" "C_c" "D_a" "D_b" "D_c" "E_a" "E_b" "E_c"

The letter combinations are created on the basis of the index positions of our two nested for-loops. If you want to know more about nested loops in R, you might check out this tutorial.

 

Example 5: Break for-Loop Based on Logical Condition

It is possible to specify a logical if-condition within a for-loop that stops the execution of the loop in case it is TRUE.

This Example explains how to stop a loop when the if-condition i >=5 is fulfilled. For this, we have to use the break-statement within the if-condition:

for(i in 1:10) {                                           # Head of for-loop
 
  x5 <- i^2                                                # Code block
  print(x5)                                                # Print results
 
  if(i >= 5) {                                             # Conditionally stop for-loop
 
    break                                                  # Using break-statement
  }
}
# [1] 1
# [1] 4
# [1] 9
# [1] 16
# [1] 25

As you can see based on the previous output of the RStudio console, our for-loop was stopped when the index i was equal to 5.

 

Example 6: Continue to Next Iteration of for-Loop

Similar to Example 5, we can also skip a for-loop iteration using the next-statement. The following for-loop is skipped at the index positions 1, 5, and 7:

for(i in 1:10) {                                           # Head of for-loop
 
  if(i %in% c(1, 5, 7)) {                                  # Conditionally skip iteration
 
    next                                                   # Using next-statement
  }
 
  x6 <- i^2                                                # Code block
  print(x6)                                                # Print results
}
# [1] 4
# [1] 9
# [1] 16
# [1] 36
# [1] 64
# [1] 81
# [1] 100

Please have a look at this tutorial in case you want to learn more on skipping iterations within for-loops.

 

Example 7: for-Loop Over Data Frame Columns

In this Example, I’ll explain how to loop through the variables of a data frame. First, let’s load some example data:

data(iris)                                                 # Loading iris flower data set
head(iris)                                                 # Inspecting iris flower data set
#   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1          5.1         3.5          1.4         0.2  setosa
# 2          4.9         3.0          1.4         0.2  setosa
# 3          4.7         3.2          1.3         0.2  setosa
# 4          4.6         3.1          1.5         0.2  setosa
# 5          5.0         3.6          1.4         0.2  setosa
# 6          5.4         3.9          1.7         0.4  setosa

Our example data frame contains five columns consisting of information on iris flowers. Let’s also replicate our data in a new data frame object called iris_new1:

iris_new1 <- iris                                          # Replicate iris data set

Now, we can loop over the columns of our data frame using the ncol function within the head of the for-statement. Within the for-loop, we are also using a logical if-condition:

for(i in 1:ncol(iris_new1)) {                              # Head of for-loop
 
  if(grepl("Width", colnames(iris_new1)[i])) {             # Logical condition
 
    iris_new1[ , i] <- iris_new1[ , i] + 1000              # Code block
  }
}

Let’s have a look at the updated data frame:

head(iris_new1)                                            # Inspecting updated iris data
#   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1          5.1      1003.5          1.4      1000.2  setosa
# 2          4.9      1003.0          1.4      1000.2  setosa
# 3          4.7      1003.2          1.3      1000.2  setosa
# 4          4.6      1003.1          1.5      1000.2  setosa
# 5          5.0      1003.6          1.4      1000.2  setosa
# 6          5.4      1003.9          1.7      1000.4  setosa

As you can see, we have added +1000 to each column that contained the character pattern “Width”.

Check out this tutorial, if you want to learn more about the looping over data frame columns and rows.

 

Example 8: Create Variable Names Using for-Loop

In Example 8, I’ll show how to create or change variable names within a for-loop. Again, let’s replicate our original data frame:

iris_new2 <- iris                                          # Replicate iris data set

Now, we can apply the colnames and paste0 functions to create new column names for each of our data frame columns:

for(i in 1:ncol(iris_new2)) {                              # Head of for-loop
 
  colnames(iris_new2)[i] <- paste0("new_", i)              # Code block
}

Let’s print the head of our updated data:

head(iris_new2)                                            # Print updated data
#   new_1 new_2 new_3 new_4  new_5
# 1   5.1   3.5   1.4   0.2 setosa
# 2   4.9   3.0   1.4   0.2 setosa
# 3   4.7   3.2   1.3   0.2 setosa
# 4   4.6   3.1   1.5   0.2 setosa
# 5   5.0   3.6   1.4   0.2 setosa
# 6   5.4   3.9   1.7   0.4 setosa

As you can see, the columns of our data frame are named with the prefix “new_” and their position within the data frame. Click here, if you want to learn more on renaming variables within loops.

 

Example 9: Creating Multiple Plots within for-Loop

for-loops can be very handy when you want to draw multiple plots efficiently within a few lines of code. Let’s assume that we want to draw a plot of each numeric column of the iris data frame. Then, we can use the following R code:

for(i in 1:(ncol(iris) - 1)) {                             # Head of for-loop
 
  plot(1:nrow(iris), iris[ , i])                           # Code block
  Sys.sleep(1)                                             # Pause code execution
}

 

r graph figure 1 for loop

 

The final plot created by the previous R code is shown in Figure 1. Note that we have specified to wait 1 sec after drawing a graph. This can also be useful when you want to create GIF-files.

I have created a more advanced tutorial on plotting data in for-loops. This tutorials also covers the ggplot2 package – a very powerful package for graphics in R.

 

Example 10: for-Loop Through List Object

In the previous examples we have applied for-loops to vectors and data frames. However, in this Example I’ll show how to write and use for-loops for the manipulation of list objects.

First, we have to create an example list:

my_list <- list(1:5,                                       # Create example list
                letters[3:1],
                "XXX")
my_list                                                    # Print example list
# [[1]]
# [1] 1 2 3 4 5
# 
# [[2]]
# [1] "c" "b" "a"
# 
# [[3]]
# [1] "XXX"

Our list consists of three different list elements. Now, we can use the length function to loop over our list:

for(i in 1:length(my_list)) {                              # Head of for-loop
 
  my_list[[i]] <- rep(my_list[[i]], 3)                     # Code block
}

Let’s have a look at the output:

my_list                                                    # Print updated list
# [[1]]
# [1] 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5
# 
# [[2]]
# [1] "c" "b" "a" "c" "b" "a" "c" "b" "a"
# 
# [[3]]
# [1] "XXX" "XXX" "XXX"

As you can see, we have replicated each list element three times.

More on this topic can be found here.

 

Alternatives to for-Loops in R

As you have seen in this article, for-loops are a beautiful weapon of the R programming language.

However, a big drawback of for-loops can be their computation time when they are not applied properly. When applied to large data sets they can be very time consuming; sometimes they might even crash R entirely.

In order to write efficient for-loops, certain guidelines should be considered. Please have a look at the article by Uwe Ligges and John Fox in this publication for a detailed discussion on the performance of loops in R.

If you want to avoid for-loops in your R code instead, you may have a look at this tutorial in case you want to learn more about alternatives such as the lapply or map functions.

 

Video & Further Resources

Do you need more explanations on the content of the present article? Then you might want to watch the following video of my YouTube channel. In the video, I illustrate the examples of this article in RStudio:

 

The YouTube video will be added soon.

 

In addition, I can recommend to have a look at the other articles of my website. Especially, you may have a look at my overview article on loops in R. It lists all related tutorials on loops, statements, and user-defined functions:

Also, please have a look at my tutorials on while- and repeat-loops – the two other types of loops provided by the R programming language. Depending on your specific data situation, one of these loop-types may be better suited for you:

In summary: In this article you learned how to apply for-loops in different settings in the R programming language. In case you have additional comments or questions, don’t hesitate to let me know in the comments section.

 

Subscribe to the Statistics Globe Newsletter

Get regular updates on the latest tutorials, offers & news at Statistics Globe.
I hate spam & you may opt out anytime: Privacy Policy.


17 Comments. Leave new

  • Hi Joachim,

    Thank you for the great content. I have a question about looping or whether it can be done using another command. I have a dataset with 1000 observations and 10 columns. It is on the diet pattern of students. It looks sth like this. if the student has eaten, it is coded a 1 and 0 for not. Now, I want to identify: no of the students who have eaten only apple, only banana, only Mango, apple and banana, apple and Mango, banana and Mango, all three fruits.

    id. apple banana Mango
    1. 1 0 0
    2. 0 1 1
    3. 1 0 0
    4. 0 1 1
    5. 1 1 0

    Reply
    • Hey Wang,

      Thank you for the kind comment, and the interesting question!

      I have tried to reproduce your problem:

      set.seed(472764)
      data <- data.frame(id = 1:50,
                         apple = rbinom(50, 1, 0.3),
                         banana = rbinom(50, 1, 0.3),
                         mango = rbinom(50, 1, 0.3))
      head(data)
      #   id apple banana mango
      # 1  1     0      0     0
      # 2  2     0      0     1
      # 3  3     1      0     0
      # 4  4     1      0     0
      # 5  5     0      1     1
      # 6  6     0      0     0
       
      nrow(data[data$apple == 1 & data$banana == 0 & data$mango == 0, ]) # Only apple
      nrow(data[data$apple == 0 & data$banana == 1 & data$mango == 0, ]) # Only banana
      nrow(data[data$apple == 0 & data$banana == 0 & data$mango == 1, ]) # Only mango
      nrow(data[data$apple == 1 & data$banana == 1 & data$mango == 0, ]) # Apple & banana
      nrow(data[data$apple == 1 & data$banana == 0 & data$mango == 1, ]) # Apple & mango
      nrow(data[data$apple == 0 & data$banana == 1 & data$mango == 1, ]) # Banana & mango
      nrow(data[data$apple == 1 & data$banana == 1 & data$mango == 1, ]) # All fruits
      nrow(data[data$apple == 0 & data$banana == 0 & data$mango == 0, ]) # No fruits

      The code above returns the desired results without using a for-loop. In case you have more combinations, you might try to make this code more efficient (for example using the expand.grid function).

      I hope that helps!

      Joachim

      Reply
  • Hi Joachim,

    I am trying to use a loop to conditionally replace some values in a data frame column.

    My data frame has 4 columns and starts like this:

    print(data)

    Correlation N Cor_type vi
    1 0.07 1292 Pearson 0.0008
    2 0.07 280 Pearson 0.0036
    3 0.12 672 Pearson 0.0015
    4 0.03 340 Pearson 0.0030
    5 0.04 155 Pearson 0.0066
    6 0.04 155 Pearson 0.0066
    7 -0.08 374 Spearman 0.0027
    8 -0.04 14 Spearman 0.0909
    9 -0.11 166 Spearman 0.0061
    10 -0.01 194 Spearman 0.0052
    (…)

    Now, I want to change the values for vi to 1/(data$N – 3) for rows with Cor_type == “Spearman” (keeping the original values for vi in all other rows). I have tried different ways to write a loop for this but cannot get it to work. I would really appreciate if you could help me with this, thanks in advance.

    Reply
  • One small correction, 1/(data$N – 3) is the formula used to create the current values of vi, for the new values the formula that should be used is 1.06/(data$N – 3).

    Reply
    • Hi again,

      You don’t need a for-loop for this. You could replace those values conditionally as demonstrated in the following example:

      data <- data.frame(Correlation = c(0.07, 0.07, 0.12, 0.03),
                         N = c(1292, 280, 672, 340),
                         Cor_type = c("Pearson", "Spearman", "Pearson", "Spearman"),
                         vi = c(0.0008, 0.0036, 0.0015, 0.0030))
      data
      #   Correlation    N Cor_type     vi
      # 1        0.07 1292  Pearson 0.0008
      # 2        0.07  280 Spearman 0.0036
      # 3        0.12  672  Pearson 0.0015
      # 4        0.03  340 Spearman 0.0030
       
      data$vi[data$Cor_type == "Spearman"] <- 1.06/(data$N[data$Cor_type == "Spearman"] - 3)
      data
      #   Correlation    N Cor_type          vi
      # 1        0.07 1292  Pearson 0.000800000
      # 2        0.07  280 Spearman 0.003826715
      # 3        0.12  672  Pearson 0.001500000
      # 4        0.03  340 Spearman 0.003145401

      I hope this helps!

      Joachim

      Reply
  • Hi Joachim,

    Thank you so much for your help! This is what I was trying to achieve.

    Constanze

    Reply
  • Hi Joachim,

    Regards for the content and uploaded videos. I have a question about “Looping Over Data Frame Rows”, I am a beginner in R and now learning how to loop. I imported my time series data from stata to r and below is the data view of the first six rows.

    Plot_id = 1 – 872
    Year = 1982 – 2021 (for each Plot_id)
    Month = 1 – 12 (for each Year)

    # Plot_id Year Month prcp Tmax Tmin
    #
    # 1 1 1982 1 0.262 32.1 15.1
    # 2 1 1982 2 5.16 32.7 18.9
    # 3 1 1982 3 44.9 33.0 21.7
    # 4 1 1982 4 142. 32.1 23.6
    # 5 1 1982 5 99.6 30.7 23.1
    # 6 1 1982 6 102. 29.4 22.4

    What I want to do?
    Do some analysis (calculate SPI & SPEI index) based on each Plot_id.

    # Loaded needed packages
    library(SPEI)
    library(haven)
    library(dplyr)

    # Importing data
    Data <- read_dta("C:/Users/DAVID/Desktop/test1/SPEI ready data/Data.dta")
    View(Data)

    # (a) calculating SPI by trying to loop
    # *******************************

    Data<- for(i in Plot_id) {
    spi3<-spi(Data$prcp,3)
    plot.spei(spi3)
    spi3
    }

    Error: "Error in Plot_id : object 'Plot_id' not found"

    # (B) calculating SPEI (using Hargreaves method) by trying to loop
    # ******************************************************

    Data<- for(i in Plot_id) {

    # Calculating PET (Potential Evapo-transpiration)
    Data$PET<-hargreaves(Tmin=Data$Tmin, Tmax = Data$Tmax, lat=9.37)
    Data$PET

    # Calculating the climatic water balance (CWBal) for SPEI
    CWBal<-Data$prcp-Data$PET

    # calculating SPEI index
    spei6<-spei(CWBal,6)
    spei6

    }

    I am able to do the analysis when I save the data based on each Plot_id but its a lot of work for 872 plots.

    Reply
    • Hey Atinga,

      Please excuse the late response. I was on a long holiday so unfortunately I wasn’t able to reply sooner. Still need help with your code?

      Regards,
      Joachim

      Reply
  • Yes I do, went through the long route and looping will save me great deal of time in my subsequent research.

    Reply
    • Hey Atinga,

      I think one problem of your loop is that the name of the data set is missing in front of the column name Plot_id.

      Another problem is that you shouldn’t assign the for-loop to a new data object.

      Please try the following code (note the Data$ in front of Plot_id):

      for(i in Data$Plot_id) {
      spi3<-spi(Data$prcp,3)
      plot.spei(spi3)
      spi3
      }

      I hope that helps!

      Joachim

      Reply
  • Hi Joachim,

    Thanks for all your valuable content.

    I need to solve this equation system for my 258 lines:

    for (i in 1:258)
    result<-solve(matrix(c((PTF[i,2]),1,(PTF[i,3]),1),nrow=2), matrix(c((PTF[i,1]),1),nrow=2))

    But R, gave me the last result, only for the 258 line. I would really appreciate if you could help me. Thank you in advance.

    Reply
  • Jeff Norriss
    March 20, 2023 3:55 am

    Best website for learning R thanks Joachim.

    Re your Example 8 entitled “Create Variable Names Using for-Loop.”
    You start with “I’ll show how to create or change variable names” (note “change” is introduced).
    Then you only show how to change names (no creation).
    I want to create a new variable inside the for loop.
    Seems I have to create something to receive the data before creating the loop???

    Thanks
    Jeff

    Reply
    • Hello Jeff,

      Creating the new column names are done in the same way as changing them. So you should simply use the code in the example. See below:

      colnames(iris_new2 )<-NULL
      head(iris_new2)
      # 1 5.1 3.5 1.4 0.2 setosa
      # 2 4.9 3.0 1.4 0.2 setosa
      # 3 4.7 3.2 1.3 0.2 setosa
      # 4 4.6 3.1 1.5 0.2 setosa
      # 5 5.0 3.6 1.4 0.2 setosa
      # 6 5.4 3.9 1.7 0.4 setosa

      for(i in 1:ncol(iris_new2)) { # Head of for-loop

      colnames(iris_new2)[i] <- paste0("new_", i) # Code block
      }
      head(iris_new2)
      # new_1 new_2 new_3 new_4 new_5
      # 1 5.1 3.5 1.4 0.2 setosa
      # 2 4.9 3.0 1.4 0.2 setosa
      # 3 4.7 3.2 1.3 0.2 setosa
      # 4 4.6 3.1 1.5 0.2 setosa
      # 5 5.0 3.6 1.4 0.2 setosa
      # 6 5.4 3.9 1.7 0.4 setosa

      Regards,
      Cansu

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.

Top