[R] for loop is looping only once

G.Maubach at weinwolf.de G.Maubach at weinwolf.de
Thu Nov 17 12:14:13 CET 2016


Hi All,

I need to execute a loop on variables to compute several KPIs. 
Unfortunately the for loop is executed only once for the last KPI given. 
The code below illustrates my current solution but is not completely 
necessary to spot the problem. I just give an idea what I am doing 
overall. Looks much but isn't if copied and run in RStudio. The problem 
occurs in function f_create_kpi_table() in lines 150 to 157:

  for (item in length(kpis))  # This loop runs only once!
  {
    print(kpis[[item]])
    ds_kpi <- f_compute_kpi(
      years    = years,
      kpi      = kpis[[item]],
      kpi_base = kpi_bases[[item]])
    print(ds_kpi)

Here is the complete example code with example data:

- cut --
dataset <-
  structure(
    list(
      to_2012 = c(
        85,
        822,
        891,
        700,
        386,
        127,
        938,
        381,
        871,
        254,
        793,
        0,
        934,
        217,
        163,
        755,
        607,
        794,
        477
      ),
      to_2013 = c(
        289,
        0,
        963,
        243,
        608,
        47,
        0,
        941,
        998,
        775,
        326,
        0,
        0,
        470,
        248,
        439,
        212,
        0,
        0
      ),
      to_2014 = c(0, 0, 71, 0, 0, 434, 0, 282, 0,
                  0, 405, 0, 0, 642, 0, 0, 0, 47, 299),
      to_2015 = c(
        705,
        134,
        659,
        0,
        609,
        807,
        783,
        0,
        0,
        304,
        141,
        500,
        0,
        0,
        764,
        790,
        851,
        0,
        802
      ),
      kpi1_2013 = c(0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0,
                    0, 0, 0, 1, 1),
      kpi1_2014 = c(1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0,
                    1, 1, 0, 1, 1, 1, 0, 0),
      kpi1_2015 = c(0, 0, 0, 1, 0, 0, 0, 1,
                    1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0),
      kpi1_2016 = c(0, 1, 0, 1, 0,
                    1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1),
      kpi2_2013 = c(1, 0,
                    1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0),
      kpi2_2014 = c(0,
                    0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1),
      kpi2_2015 = c(1,
                    1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1),
      kpi2_2016 = c(1,
                    0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0)
    ),
    .Names = c(
      "to_2012",
      "to_2013",
      "to_2014",
      "to_2015",
      "kpi1_2013",
      "kpi1_2014",
      "kpi1_2015",
      "kpi1_2016",
      "kpi2_2013",
      "kpi2_2014",
      "kpi2_2015",
      "kpi2_2016"
    ),
    row.names = c(NA, 19L),
    class = "data.frame"
  )

f_compute_kpi <- function(
  years,
  kpi,
  kpi_base)
{
  print(years)
  print(kpi)
  print(kpi_base)

  ds_result <- data.frame()

  for (year in years) {
    current_year  <- year
    previous_year <- year - 1
    result <- sum(dataset[dataset[[paste0(kpi,
                                          "_",
                                          current_year)]] == 1 ,
                          paste0(kpi_base,
                                 "_", previous_year)],
                  na.rm = TRUE)
    ds_result <- rbind(ds_result, result)
  }

  ds_result           <- t(ds_result)
  rownames(ds_result) <- kpi
  colnames(ds_result) <- years

  invisible(ds_result)
}

f_create_kpi_table <- function(
  years,
  kpis,
  kpi_bases)
{
  print(length(kpis))

#-- Problematic loop --
  for (item in length(kpis))  # This loop runs only once!
  {
    print(kpis[[item]])
    ds_kpi <- f_compute_kpi(
      years    = years,
      kpi      = kpis[[item]],
      kpi_base = kpi_bases[[item]])
    print(ds_kpi)
  }
  # This for loop is executed only once for kpi2 instead of
  # as many times as given kpis in length(kpis), i. e.
  # kpi1 AND kpi2.
  # Why?
  # What do I do wrong?
}
-- cut --

What do I need to change to get the loop work correctly and loop over two 
elements instead of one when calling the function

f_create_kpi_table(years = 2013:2016, kpis = c("kpi1", "kpi2"), kpi_bases 
= c("to", "to"))

Kind regards

Georg



More information about the R-help mailing list