Lapply and for loop produce different result when creating graphs dynamically





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















first time asking question here so if I mess up something, please let me know I'll be happy to fix it.



While trying to dynamically create multiple graphs generated by ggplot2 and then print the graphs using gridExtra::grid.arrange, I noticed that using a for loop or using lapply produce different results.



Surprisingly, while lapply produces the expected result, the graphs created with the for loop end up with having all the same y data.



Here is a reproducible example:



library(ggplot2)
library(gridExtra)

gen.plot <- function(df, x.colName, y.colName, title,
movavg.period) {
# print(y.colName)
p <- ggplot(df, aes(x = df[[x.colName]],
y = df[[y.colName]])) +
geom_line() +
xlab("Time") +
ylab("Value") +
ggtitle(title)

return(p)
}

titles <- c("down", "mid", "up")
df <- data.frame(tick = seq(0, 10, 1),
down = seq(2, 1, -0.1),
mid = rep(3, 11),
up = seq(5,6, 0.1))

plots.list <- list()
for(t in titles) {
plots.list[[length(plots.list) + 1]] <- gen.plot(df, "tick",
t, t, 2)
}
grid.arrange(grobs = plots.list, nrow = 3)

plots.list <- lapply(titles, FUN = function(t, lapply.df) {
gen.plot(lapply.df, "tick",
t, t, 2)
}, lapply.df = df)

grid.arrange(grobs = plots.list, nrow = 3)


Now, where it becomes really weird, is that if you uncomment the print call in the function that prints out the y.colName variable, the for loop works as expected. But it only works if you print out this specific variable, not any of the other function variable. Also, as you can see in the code, the y.colName variable is used in the title of the graph, and the title is correct in every graph.



Also, I've tried taking the code out of the function but it provides the same results and the print call trick does not work anymore.



I can't post image without 10 reputation so links will have to do.



Here is what I get with the for loop:
forloop



Here is what I get with lapply:
lapply



Here is my sessionInfo():



R version 3.4.3 (2017-11-30)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

Matrix products: default

locale:
[1] LC_COLLATE=English_Ireland.1252 LC_CTYPE=English_Ireland.1252
[3] LC_MONETARY=English_Ireland.1252 LC_NUMERIC=C
[5] LC_TIME=English_Ireland.1252

attached base packages:
[1] stats graphics grDevices utils datasets methods base

other attached packages:
[1] gridExtra_2.3 ggplot2_2.2.1

loaded via a namespace (and not attached):
[1] labeling_0.3 colorspace_1.3-2 scales_0.5.0 compiler_3.4.3
[5] lazyeval_0.2.0 plyr_1.8.4 tools_3.4.3 pillar_1.2.1
[9] gtable_0.2.0 tibble_1.4.2 yaml_2.1.14 Rcpp_0.12.16
[13] grid_3.4.3 rlang_0.2.0 munsell_0.4.3


Please, if you understand what's happening here, explain it to me, help me get my sleep back.










share|improve this question

























  • When you use a for loop, only the last iteration is rendered. You can read the explanation to a similar question here. This is also a good read that goes into how ggplot creates a graph.

    – Z.Lin
    Nov 30 '18 at 10:06


















0















first time asking question here so if I mess up something, please let me know I'll be happy to fix it.



While trying to dynamically create multiple graphs generated by ggplot2 and then print the graphs using gridExtra::grid.arrange, I noticed that using a for loop or using lapply produce different results.



Surprisingly, while lapply produces the expected result, the graphs created with the for loop end up with having all the same y data.



Here is a reproducible example:



library(ggplot2)
library(gridExtra)

gen.plot <- function(df, x.colName, y.colName, title,
movavg.period) {
# print(y.colName)
p <- ggplot(df, aes(x = df[[x.colName]],
y = df[[y.colName]])) +
geom_line() +
xlab("Time") +
ylab("Value") +
ggtitle(title)

return(p)
}

titles <- c("down", "mid", "up")
df <- data.frame(tick = seq(0, 10, 1),
down = seq(2, 1, -0.1),
mid = rep(3, 11),
up = seq(5,6, 0.1))

plots.list <- list()
for(t in titles) {
plots.list[[length(plots.list) + 1]] <- gen.plot(df, "tick",
t, t, 2)
}
grid.arrange(grobs = plots.list, nrow = 3)

plots.list <- lapply(titles, FUN = function(t, lapply.df) {
gen.plot(lapply.df, "tick",
t, t, 2)
}, lapply.df = df)

grid.arrange(grobs = plots.list, nrow = 3)


Now, where it becomes really weird, is that if you uncomment the print call in the function that prints out the y.colName variable, the for loop works as expected. But it only works if you print out this specific variable, not any of the other function variable. Also, as you can see in the code, the y.colName variable is used in the title of the graph, and the title is correct in every graph.



Also, I've tried taking the code out of the function but it provides the same results and the print call trick does not work anymore.



I can't post image without 10 reputation so links will have to do.



Here is what I get with the for loop:
forloop



Here is what I get with lapply:
lapply



Here is my sessionInfo():



R version 3.4.3 (2017-11-30)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

Matrix products: default

locale:
[1] LC_COLLATE=English_Ireland.1252 LC_CTYPE=English_Ireland.1252
[3] LC_MONETARY=English_Ireland.1252 LC_NUMERIC=C
[5] LC_TIME=English_Ireland.1252

attached base packages:
[1] stats graphics grDevices utils datasets methods base

other attached packages:
[1] gridExtra_2.3 ggplot2_2.2.1

loaded via a namespace (and not attached):
[1] labeling_0.3 colorspace_1.3-2 scales_0.5.0 compiler_3.4.3
[5] lazyeval_0.2.0 plyr_1.8.4 tools_3.4.3 pillar_1.2.1
[9] gtable_0.2.0 tibble_1.4.2 yaml_2.1.14 Rcpp_0.12.16
[13] grid_3.4.3 rlang_0.2.0 munsell_0.4.3


Please, if you understand what's happening here, explain it to me, help me get my sleep back.










share|improve this question

























  • When you use a for loop, only the last iteration is rendered. You can read the explanation to a similar question here. This is also a good read that goes into how ggplot creates a graph.

    – Z.Lin
    Nov 30 '18 at 10:06














0












0








0








first time asking question here so if I mess up something, please let me know I'll be happy to fix it.



While trying to dynamically create multiple graphs generated by ggplot2 and then print the graphs using gridExtra::grid.arrange, I noticed that using a for loop or using lapply produce different results.



Surprisingly, while lapply produces the expected result, the graphs created with the for loop end up with having all the same y data.



Here is a reproducible example:



library(ggplot2)
library(gridExtra)

gen.plot <- function(df, x.colName, y.colName, title,
movavg.period) {
# print(y.colName)
p <- ggplot(df, aes(x = df[[x.colName]],
y = df[[y.colName]])) +
geom_line() +
xlab("Time") +
ylab("Value") +
ggtitle(title)

return(p)
}

titles <- c("down", "mid", "up")
df <- data.frame(tick = seq(0, 10, 1),
down = seq(2, 1, -0.1),
mid = rep(3, 11),
up = seq(5,6, 0.1))

plots.list <- list()
for(t in titles) {
plots.list[[length(plots.list) + 1]] <- gen.plot(df, "tick",
t, t, 2)
}
grid.arrange(grobs = plots.list, nrow = 3)

plots.list <- lapply(titles, FUN = function(t, lapply.df) {
gen.plot(lapply.df, "tick",
t, t, 2)
}, lapply.df = df)

grid.arrange(grobs = plots.list, nrow = 3)


Now, where it becomes really weird, is that if you uncomment the print call in the function that prints out the y.colName variable, the for loop works as expected. But it only works if you print out this specific variable, not any of the other function variable. Also, as you can see in the code, the y.colName variable is used in the title of the graph, and the title is correct in every graph.



Also, I've tried taking the code out of the function but it provides the same results and the print call trick does not work anymore.



I can't post image without 10 reputation so links will have to do.



Here is what I get with the for loop:
forloop



Here is what I get with lapply:
lapply



Here is my sessionInfo():



R version 3.4.3 (2017-11-30)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

Matrix products: default

locale:
[1] LC_COLLATE=English_Ireland.1252 LC_CTYPE=English_Ireland.1252
[3] LC_MONETARY=English_Ireland.1252 LC_NUMERIC=C
[5] LC_TIME=English_Ireland.1252

attached base packages:
[1] stats graphics grDevices utils datasets methods base

other attached packages:
[1] gridExtra_2.3 ggplot2_2.2.1

loaded via a namespace (and not attached):
[1] labeling_0.3 colorspace_1.3-2 scales_0.5.0 compiler_3.4.3
[5] lazyeval_0.2.0 plyr_1.8.4 tools_3.4.3 pillar_1.2.1
[9] gtable_0.2.0 tibble_1.4.2 yaml_2.1.14 Rcpp_0.12.16
[13] grid_3.4.3 rlang_0.2.0 munsell_0.4.3


Please, if you understand what's happening here, explain it to me, help me get my sleep back.










share|improve this question
















first time asking question here so if I mess up something, please let me know I'll be happy to fix it.



While trying to dynamically create multiple graphs generated by ggplot2 and then print the graphs using gridExtra::grid.arrange, I noticed that using a for loop or using lapply produce different results.



Surprisingly, while lapply produces the expected result, the graphs created with the for loop end up with having all the same y data.



Here is a reproducible example:



library(ggplot2)
library(gridExtra)

gen.plot <- function(df, x.colName, y.colName, title,
movavg.period) {
# print(y.colName)
p <- ggplot(df, aes(x = df[[x.colName]],
y = df[[y.colName]])) +
geom_line() +
xlab("Time") +
ylab("Value") +
ggtitle(title)

return(p)
}

titles <- c("down", "mid", "up")
df <- data.frame(tick = seq(0, 10, 1),
down = seq(2, 1, -0.1),
mid = rep(3, 11),
up = seq(5,6, 0.1))

plots.list <- list()
for(t in titles) {
plots.list[[length(plots.list) + 1]] <- gen.plot(df, "tick",
t, t, 2)
}
grid.arrange(grobs = plots.list, nrow = 3)

plots.list <- lapply(titles, FUN = function(t, lapply.df) {
gen.plot(lapply.df, "tick",
t, t, 2)
}, lapply.df = df)

grid.arrange(grobs = plots.list, nrow = 3)


Now, where it becomes really weird, is that if you uncomment the print call in the function that prints out the y.colName variable, the for loop works as expected. But it only works if you print out this specific variable, not any of the other function variable. Also, as you can see in the code, the y.colName variable is used in the title of the graph, and the title is correct in every graph.



Also, I've tried taking the code out of the function but it provides the same results and the print call trick does not work anymore.



I can't post image without 10 reputation so links will have to do.



Here is what I get with the for loop:
forloop



Here is what I get with lapply:
lapply



Here is my sessionInfo():



R version 3.4.3 (2017-11-30)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

Matrix products: default

locale:
[1] LC_COLLATE=English_Ireland.1252 LC_CTYPE=English_Ireland.1252
[3] LC_MONETARY=English_Ireland.1252 LC_NUMERIC=C
[5] LC_TIME=English_Ireland.1252

attached base packages:
[1] stats graphics grDevices utils datasets methods base

other attached packages:
[1] gridExtra_2.3 ggplot2_2.2.1

loaded via a namespace (and not attached):
[1] labeling_0.3 colorspace_1.3-2 scales_0.5.0 compiler_3.4.3
[5] lazyeval_0.2.0 plyr_1.8.4 tools_3.4.3 pillar_1.2.1
[9] gtable_0.2.0 tibble_1.4.2 yaml_2.1.14 Rcpp_0.12.16
[13] grid_3.4.3 rlang_0.2.0 munsell_0.4.3


Please, if you understand what's happening here, explain it to me, help me get my sleep back.







r for-loop ggplot2 lapply gridextra






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 23 '18 at 12:45









P. Paccioretti

16627




16627










asked Nov 23 '18 at 12:16









QuentinQuentin

11




11













  • When you use a for loop, only the last iteration is rendered. You can read the explanation to a similar question here. This is also a good read that goes into how ggplot creates a graph.

    – Z.Lin
    Nov 30 '18 at 10:06



















  • When you use a for loop, only the last iteration is rendered. You can read the explanation to a similar question here. This is also a good read that goes into how ggplot creates a graph.

    – Z.Lin
    Nov 30 '18 at 10:06

















When you use a for loop, only the last iteration is rendered. You can read the explanation to a similar question here. This is also a good read that goes into how ggplot creates a graph.

– Z.Lin
Nov 30 '18 at 10:06





When you use a for loop, only the last iteration is rendered. You can read the explanation to a similar question here. This is also a good read that goes into how ggplot creates a graph.

– Z.Lin
Nov 30 '18 at 10:06












1 Answer
1






active

oldest

votes


















0














Try this:



gen.plot <- function(df, x.colName, y.colName, title,
movavg.period) {
# print(y.colName)
p <- ggplot(df, aes_string(x = x.colName,
y = y.colName)) +
geom_line() +
xlab("Time") +
ylab("Value") +
ggtitle(title)

return(p)
}


It should give you consist and correct results whichever method you use to implement it (i.e., lapply or for loop). Using ggplot2 in this way allows you to specify the variable names using a string. And you should be specifying variable names and not giving aes the entire column from the data frame.






share|improve this answer


























  • Thanks for you answer @Lyngbakr. It does produce the same results for both lapply and for using aes_string. However, what I'm more interested in is why it does not produce the same results in the case that I showed previously. What's the underlying difference between for and lapply that makes the code works in one case and not the other, as well as why printing the content of the variable change the outcome of the code.

    – Quentin
    Nov 23 '18 at 12:40














Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53446578%2flapply-and-for-loop-produce-different-result-when-creating-graphs-dynamically%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














Try this:



gen.plot <- function(df, x.colName, y.colName, title,
movavg.period) {
# print(y.colName)
p <- ggplot(df, aes_string(x = x.colName,
y = y.colName)) +
geom_line() +
xlab("Time") +
ylab("Value") +
ggtitle(title)

return(p)
}


It should give you consist and correct results whichever method you use to implement it (i.e., lapply or for loop). Using ggplot2 in this way allows you to specify the variable names using a string. And you should be specifying variable names and not giving aes the entire column from the data frame.






share|improve this answer


























  • Thanks for you answer @Lyngbakr. It does produce the same results for both lapply and for using aes_string. However, what I'm more interested in is why it does not produce the same results in the case that I showed previously. What's the underlying difference between for and lapply that makes the code works in one case and not the other, as well as why printing the content of the variable change the outcome of the code.

    – Quentin
    Nov 23 '18 at 12:40


















0














Try this:



gen.plot <- function(df, x.colName, y.colName, title,
movavg.period) {
# print(y.colName)
p <- ggplot(df, aes_string(x = x.colName,
y = y.colName)) +
geom_line() +
xlab("Time") +
ylab("Value") +
ggtitle(title)

return(p)
}


It should give you consist and correct results whichever method you use to implement it (i.e., lapply or for loop). Using ggplot2 in this way allows you to specify the variable names using a string. And you should be specifying variable names and not giving aes the entire column from the data frame.






share|improve this answer


























  • Thanks for you answer @Lyngbakr. It does produce the same results for both lapply and for using aes_string. However, what I'm more interested in is why it does not produce the same results in the case that I showed previously. What's the underlying difference between for and lapply that makes the code works in one case and not the other, as well as why printing the content of the variable change the outcome of the code.

    – Quentin
    Nov 23 '18 at 12:40
















0












0








0







Try this:



gen.plot <- function(df, x.colName, y.colName, title,
movavg.period) {
# print(y.colName)
p <- ggplot(df, aes_string(x = x.colName,
y = y.colName)) +
geom_line() +
xlab("Time") +
ylab("Value") +
ggtitle(title)

return(p)
}


It should give you consist and correct results whichever method you use to implement it (i.e., lapply or for loop). Using ggplot2 in this way allows you to specify the variable names using a string. And you should be specifying variable names and not giving aes the entire column from the data frame.






share|improve this answer















Try this:



gen.plot <- function(df, x.colName, y.colName, title,
movavg.period) {
# print(y.colName)
p <- ggplot(df, aes_string(x = x.colName,
y = y.colName)) +
geom_line() +
xlab("Time") +
ylab("Value") +
ggtitle(title)

return(p)
}


It should give you consist and correct results whichever method you use to implement it (i.e., lapply or for loop). Using ggplot2 in this way allows you to specify the variable names using a string. And you should be specifying variable names and not giving aes the entire column from the data frame.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 23 '18 at 12:33

























answered Nov 23 '18 at 12:27









LyngbakrLyngbakr

5,45811428




5,45811428













  • Thanks for you answer @Lyngbakr. It does produce the same results for both lapply and for using aes_string. However, what I'm more interested in is why it does not produce the same results in the case that I showed previously. What's the underlying difference between for and lapply that makes the code works in one case and not the other, as well as why printing the content of the variable change the outcome of the code.

    – Quentin
    Nov 23 '18 at 12:40





















  • Thanks for you answer @Lyngbakr. It does produce the same results for both lapply and for using aes_string. However, what I'm more interested in is why it does not produce the same results in the case that I showed previously. What's the underlying difference between for and lapply that makes the code works in one case and not the other, as well as why printing the content of the variable change the outcome of the code.

    – Quentin
    Nov 23 '18 at 12:40



















Thanks for you answer @Lyngbakr. It does produce the same results for both lapply and for using aes_string. However, what I'm more interested in is why it does not produce the same results in the case that I showed previously. What's the underlying difference between for and lapply that makes the code works in one case and not the other, as well as why printing the content of the variable change the outcome of the code.

– Quentin
Nov 23 '18 at 12:40







Thanks for you answer @Lyngbakr. It does produce the same results for both lapply and for using aes_string. However, what I'm more interested in is why it does not produce the same results in the case that I showed previously. What's the underlying difference between for and lapply that makes the code works in one case and not the other, as well as why printing the content of the variable change the outcome of the code.

– Quentin
Nov 23 '18 at 12:40






















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53446578%2flapply-and-for-loop-produce-different-result-when-creating-graphs-dynamically%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

"Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

Alcedinidae

Origin of the phrase “under your belt”?