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
Hi Georg, Your for loop iterates over just one value, to get it to work as you intend use for(item in 1:length(kpis)){} HTH Ulrik On Thu, 17 Nov 2016 at 12:18 <G.Maubach at weinwolf.de> wrote:> 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 > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >[[alternative HTML version deleted]]
G.Maubach at weinwolf.de
2016-Nov-17 11:33 UTC
[R] Antwort: Re: for loop is looping only once [SOLVED]
Hi Ulrik, oh no! What a mistake did I make. But I definitely did not see the failure. Many thanks for helping me. Kind regards Georg Von: Ulrik Stervbo <ulrik.stervbo at gmail.com> An: G.Maubach at weinwolf.de, r-help at r-project.org, Datum: 17.11.2016 12:24 Betreff: Re: [R] for loop is looping only once Hi Georg, Your for loop iterates over just one value, to get it to work as you intend use for(item in 1:length(kpis)){} HTH Ulrik On Thu, 17 Nov 2016 at 12:18 <G.Maubach at weinwolf.de> wrote: 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 ______________________________________________ R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
On 17/11/2016 6:26 AM, Ulrik Stervbo wrote:> Hi Georg, > > Your for loop iterates over just one value, to get it to work as you intend > use for(item in 1:length(kpis)){}That usually works, but fails often enough that we recommend using for (item in seq_along(kpis)) {} (The failures happen if length(kpis) is zero. 1:0 is a length 2 vector, not a length 0 one.) Duncan Murdoch> > HTH > Ulrik > > On Thu, 17 Nov 2016 at 12:18 <G.Maubach at weinwolf.de> wrote: > >> 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 >> >> ______________________________________________ >> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >> https://stat.ethz.ch/mailman/listinfo/r-help >> PLEASE do read the posting guide >> http://www.R-project.org/posting-guide.html >> and provide commented, minimal, self-contained, reproducible code. >> > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >