use a counter to access named list elements as ggtitle within mapply call





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







0















I'm generating and plotting multiple ggplots based on data from two lists, therefore I'm using mapply. One of the lists has named elements, which I would like to use as ggtitle. But it only takes the first element for all the plots



> names(sample_subset_list)
[1] "water after day 43 dna min reads per OTU 5"
[2] "biofilm after day 43 dna min reads per OTU 5"
[3] "water after day 43 cdna min reads per OTU 5"
[4] "biofilm after day 43 cdna min reads per OTU 5"
[5] "water after day 44 dna min reads per OTU 5"
[6] "biofilm after day 44 dna min reads per OTU 5"
[7] "water after day 44 cdna min reads per OTU 5"
[8] "biofilm after day 44 cdna min reads per OTU 5"


and this is the plotting function:



ordination_plots <- list()
counter <- 0
ordination_plots <- mapply(function(x,y,counter) {
counter <- counter + 1
plot_ordination(x, y, type = "sample") +
ggtitle(names(sample_subset_list)[counter]) +
}, x = sample_subset_list, y = ordination_nmds, counter = 0, SIMPLIFY = FALSE)


this will give me plots where the title is always the first element of



names(sample_subset_list).



The same happens calling ggtitle(names(sample_subset_list)) +



If I use counter <<- (suggested here: Using a counter inside an apply structured loop in R) or call ggtitle like



ggtitle(names(sample_subset_list)) +



or



ggtitle(names(sample_subset_list)[]) +



I get no title at all.



I started without a counter, which also gave me the same title for all plots. Could someone explain to me how I can iterate over the names of the list elements to use them for the ggplots?










share|improve this question

























  • you passed counter as a parameter and are only modifying it locally. To modify it in the parent scope you need to use <<-. I'd remove it from the function def and mapply parameter list, too.

    – hrbrmstr
    Nov 23 '18 at 14:56











  • @hrbrmstr that worked, thanks! But I have to admit that I don't really understand, why it worked. Do you want to add this as answer and make it a little bit clearer?

    – crazysantaclaus
    Nov 23 '18 at 15:01


















0















I'm generating and plotting multiple ggplots based on data from two lists, therefore I'm using mapply. One of the lists has named elements, which I would like to use as ggtitle. But it only takes the first element for all the plots



> names(sample_subset_list)
[1] "water after day 43 dna min reads per OTU 5"
[2] "biofilm after day 43 dna min reads per OTU 5"
[3] "water after day 43 cdna min reads per OTU 5"
[4] "biofilm after day 43 cdna min reads per OTU 5"
[5] "water after day 44 dna min reads per OTU 5"
[6] "biofilm after day 44 dna min reads per OTU 5"
[7] "water after day 44 cdna min reads per OTU 5"
[8] "biofilm after day 44 cdna min reads per OTU 5"


and this is the plotting function:



ordination_plots <- list()
counter <- 0
ordination_plots <- mapply(function(x,y,counter) {
counter <- counter + 1
plot_ordination(x, y, type = "sample") +
ggtitle(names(sample_subset_list)[counter]) +
}, x = sample_subset_list, y = ordination_nmds, counter = 0, SIMPLIFY = FALSE)


this will give me plots where the title is always the first element of



names(sample_subset_list).



The same happens calling ggtitle(names(sample_subset_list)) +



If I use counter <<- (suggested here: Using a counter inside an apply structured loop in R) or call ggtitle like



ggtitle(names(sample_subset_list)) +



or



ggtitle(names(sample_subset_list)[]) +



I get no title at all.



I started without a counter, which also gave me the same title for all plots. Could someone explain to me how I can iterate over the names of the list elements to use them for the ggplots?










share|improve this question

























  • you passed counter as a parameter and are only modifying it locally. To modify it in the parent scope you need to use <<-. I'd remove it from the function def and mapply parameter list, too.

    – hrbrmstr
    Nov 23 '18 at 14:56











  • @hrbrmstr that worked, thanks! But I have to admit that I don't really understand, why it worked. Do you want to add this as answer and make it a little bit clearer?

    – crazysantaclaus
    Nov 23 '18 at 15:01














0












0








0








I'm generating and plotting multiple ggplots based on data from two lists, therefore I'm using mapply. One of the lists has named elements, which I would like to use as ggtitle. But it only takes the first element for all the plots



> names(sample_subset_list)
[1] "water after day 43 dna min reads per OTU 5"
[2] "biofilm after day 43 dna min reads per OTU 5"
[3] "water after day 43 cdna min reads per OTU 5"
[4] "biofilm after day 43 cdna min reads per OTU 5"
[5] "water after day 44 dna min reads per OTU 5"
[6] "biofilm after day 44 dna min reads per OTU 5"
[7] "water after day 44 cdna min reads per OTU 5"
[8] "biofilm after day 44 cdna min reads per OTU 5"


and this is the plotting function:



ordination_plots <- list()
counter <- 0
ordination_plots <- mapply(function(x,y,counter) {
counter <- counter + 1
plot_ordination(x, y, type = "sample") +
ggtitle(names(sample_subset_list)[counter]) +
}, x = sample_subset_list, y = ordination_nmds, counter = 0, SIMPLIFY = FALSE)


this will give me plots where the title is always the first element of



names(sample_subset_list).



The same happens calling ggtitle(names(sample_subset_list)) +



If I use counter <<- (suggested here: Using a counter inside an apply structured loop in R) or call ggtitle like



ggtitle(names(sample_subset_list)) +



or



ggtitle(names(sample_subset_list)[]) +



I get no title at all.



I started without a counter, which also gave me the same title for all plots. Could someone explain to me how I can iterate over the names of the list elements to use them for the ggplots?










share|improve this question
















I'm generating and plotting multiple ggplots based on data from two lists, therefore I'm using mapply. One of the lists has named elements, which I would like to use as ggtitle. But it only takes the first element for all the plots



> names(sample_subset_list)
[1] "water after day 43 dna min reads per OTU 5"
[2] "biofilm after day 43 dna min reads per OTU 5"
[3] "water after day 43 cdna min reads per OTU 5"
[4] "biofilm after day 43 cdna min reads per OTU 5"
[5] "water after day 44 dna min reads per OTU 5"
[6] "biofilm after day 44 dna min reads per OTU 5"
[7] "water after day 44 cdna min reads per OTU 5"
[8] "biofilm after day 44 cdna min reads per OTU 5"


and this is the plotting function:



ordination_plots <- list()
counter <- 0
ordination_plots <- mapply(function(x,y,counter) {
counter <- counter + 1
plot_ordination(x, y, type = "sample") +
ggtitle(names(sample_subset_list)[counter]) +
}, x = sample_subset_list, y = ordination_nmds, counter = 0, SIMPLIFY = FALSE)


this will give me plots where the title is always the first element of



names(sample_subset_list).



The same happens calling ggtitle(names(sample_subset_list)) +



If I use counter <<- (suggested here: Using a counter inside an apply structured loop in R) or call ggtitle like



ggtitle(names(sample_subset_list)) +



or



ggtitle(names(sample_subset_list)[]) +



I get no title at all.



I started without a counter, which also gave me the same title for all plots. Could someone explain to me how I can iterate over the names of the list elements to use them for the ggplots?







r mapply






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 23 '18 at 16:44







crazysantaclaus

















asked Nov 23 '18 at 14:55









crazysantaclauscrazysantaclaus

302110




302110













  • you passed counter as a parameter and are only modifying it locally. To modify it in the parent scope you need to use <<-. I'd remove it from the function def and mapply parameter list, too.

    – hrbrmstr
    Nov 23 '18 at 14:56











  • @hrbrmstr that worked, thanks! But I have to admit that I don't really understand, why it worked. Do you want to add this as answer and make it a little bit clearer?

    – crazysantaclaus
    Nov 23 '18 at 15:01



















  • you passed counter as a parameter and are only modifying it locally. To modify it in the parent scope you need to use <<-. I'd remove it from the function def and mapply parameter list, too.

    – hrbrmstr
    Nov 23 '18 at 14:56











  • @hrbrmstr that worked, thanks! But I have to admit that I don't really understand, why it worked. Do you want to add this as answer and make it a little bit clearer?

    – crazysantaclaus
    Nov 23 '18 at 15:01

















you passed counter as a parameter and are only modifying it locally. To modify it in the parent scope you need to use <<-. I'd remove it from the function def and mapply parameter list, too.

– hrbrmstr
Nov 23 '18 at 14:56





you passed counter as a parameter and are only modifying it locally. To modify it in the parent scope you need to use <<-. I'd remove it from the function def and mapply parameter list, too.

– hrbrmstr
Nov 23 '18 at 14:56













@hrbrmstr that worked, thanks! But I have to admit that I don't really understand, why it worked. Do you want to add this as answer and make it a little bit clearer?

– crazysantaclaus
Nov 23 '18 at 15:01





@hrbrmstr that worked, thanks! But I have to admit that I don't really understand, why it worked. Do you want to add this as answer and make it a little bit clearer?

– crazysantaclaus
Nov 23 '18 at 15:01












1 Answer
1






active

oldest

votes


















2














Let's reduce the complexity of the example:



counter <- 0

invisible(mapply(function(letter, counter) {

counter <- counter + 1
cat("Letter: ", letter, "; Counter: ", counter, "n", sep="")

}, letters[1:10], counter))


NOTE: I only used invisible() to stop printing the result of mapply().



letters[1:10] is a 10-element vector of lower-case letter (built in data).



You define counter outside of mapply(). Unlike for or while, functions in mapply() do not — by default — create or modify variables in the parent scope (outside of mapply(), so the result is this:



Letter: a; Counter: 1
Letter: b; Counter: 1
Letter: c; Counter: 1
Letter: d; Counter: 1
Letter: e; Counter: 1
Letter: f; Counter: 1
Letter: g; Counter: 1
Letter: h; Counter: 1
Letter: i; Counter: 1
Letter: j; Counter: 1


It's fine to pass in a second parameter with info to the function argument of mapply() but if the intent is to have a side-effect of incrementing something outside the scope of the function in mapply() then you really shouldn't pass it to in as parameter and just modify it using the <<- operator, which — according to the help page:



"The operators <<- and ->> are normally only used in functions, and cause a search to be made through parent environments for an existing definition of the variable being assigned. If such a variable is found (and its binding is not locked) then its value is redefined, otherwise assignment takes place in the global environment."



So, we can just do this:



# TO MY FUTURE SELF AND TEAM MEMBERS
# `counter` is modified as a side-effect of operations in the `mapply()`
# that follows the object declaration
counter <- 0

invisible(mapply(function(letter) {

counter <<- counter + 1
cat("Letter: ", letter, "; Counter: ", counter, "n", sep="")

}, letters[1:10]))


to get this:



Letter: a; Counter: 1
Letter: b; Counter: 2
Letter: c; Counter: 3
Letter: d; Counter: 4
Letter: e; Counter: 5
Letter: f; Counter: 6
Letter: g; Counter: 7
Letter: h; Counter: 8
Letter: i; Counter: 9
Letter: j; Counter: 10


The comment was not meant for snark. You are using a side-effect that may be non-obvious to your future self or folks you share the code with so noting it will help you re-figure out and them figure out what's happening.






share|improve this answer
























  • alright, so I mixed defining a parameter inside the function called counter with updating a counter which was not part of the function. Thank you very much for the detailed explanation.

    – crazysantaclaus
    Nov 23 '18 at 16:43












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%2f53448884%2fuse-a-counter-to-access-named-list-elements-as-ggtitle-within-mapply-call%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









2














Let's reduce the complexity of the example:



counter <- 0

invisible(mapply(function(letter, counter) {

counter <- counter + 1
cat("Letter: ", letter, "; Counter: ", counter, "n", sep="")

}, letters[1:10], counter))


NOTE: I only used invisible() to stop printing the result of mapply().



letters[1:10] is a 10-element vector of lower-case letter (built in data).



You define counter outside of mapply(). Unlike for or while, functions in mapply() do not — by default — create or modify variables in the parent scope (outside of mapply(), so the result is this:



Letter: a; Counter: 1
Letter: b; Counter: 1
Letter: c; Counter: 1
Letter: d; Counter: 1
Letter: e; Counter: 1
Letter: f; Counter: 1
Letter: g; Counter: 1
Letter: h; Counter: 1
Letter: i; Counter: 1
Letter: j; Counter: 1


It's fine to pass in a second parameter with info to the function argument of mapply() but if the intent is to have a side-effect of incrementing something outside the scope of the function in mapply() then you really shouldn't pass it to in as parameter and just modify it using the <<- operator, which — according to the help page:



"The operators <<- and ->> are normally only used in functions, and cause a search to be made through parent environments for an existing definition of the variable being assigned. If such a variable is found (and its binding is not locked) then its value is redefined, otherwise assignment takes place in the global environment."



So, we can just do this:



# TO MY FUTURE SELF AND TEAM MEMBERS
# `counter` is modified as a side-effect of operations in the `mapply()`
# that follows the object declaration
counter <- 0

invisible(mapply(function(letter) {

counter <<- counter + 1
cat("Letter: ", letter, "; Counter: ", counter, "n", sep="")

}, letters[1:10]))


to get this:



Letter: a; Counter: 1
Letter: b; Counter: 2
Letter: c; Counter: 3
Letter: d; Counter: 4
Letter: e; Counter: 5
Letter: f; Counter: 6
Letter: g; Counter: 7
Letter: h; Counter: 8
Letter: i; Counter: 9
Letter: j; Counter: 10


The comment was not meant for snark. You are using a side-effect that may be non-obvious to your future self or folks you share the code with so noting it will help you re-figure out and them figure out what's happening.






share|improve this answer
























  • alright, so I mixed defining a parameter inside the function called counter with updating a counter which was not part of the function. Thank you very much for the detailed explanation.

    – crazysantaclaus
    Nov 23 '18 at 16:43
















2














Let's reduce the complexity of the example:



counter <- 0

invisible(mapply(function(letter, counter) {

counter <- counter + 1
cat("Letter: ", letter, "; Counter: ", counter, "n", sep="")

}, letters[1:10], counter))


NOTE: I only used invisible() to stop printing the result of mapply().



letters[1:10] is a 10-element vector of lower-case letter (built in data).



You define counter outside of mapply(). Unlike for or while, functions in mapply() do not — by default — create or modify variables in the parent scope (outside of mapply(), so the result is this:



Letter: a; Counter: 1
Letter: b; Counter: 1
Letter: c; Counter: 1
Letter: d; Counter: 1
Letter: e; Counter: 1
Letter: f; Counter: 1
Letter: g; Counter: 1
Letter: h; Counter: 1
Letter: i; Counter: 1
Letter: j; Counter: 1


It's fine to pass in a second parameter with info to the function argument of mapply() but if the intent is to have a side-effect of incrementing something outside the scope of the function in mapply() then you really shouldn't pass it to in as parameter and just modify it using the <<- operator, which — according to the help page:



"The operators <<- and ->> are normally only used in functions, and cause a search to be made through parent environments for an existing definition of the variable being assigned. If such a variable is found (and its binding is not locked) then its value is redefined, otherwise assignment takes place in the global environment."



So, we can just do this:



# TO MY FUTURE SELF AND TEAM MEMBERS
# `counter` is modified as a side-effect of operations in the `mapply()`
# that follows the object declaration
counter <- 0

invisible(mapply(function(letter) {

counter <<- counter + 1
cat("Letter: ", letter, "; Counter: ", counter, "n", sep="")

}, letters[1:10]))


to get this:



Letter: a; Counter: 1
Letter: b; Counter: 2
Letter: c; Counter: 3
Letter: d; Counter: 4
Letter: e; Counter: 5
Letter: f; Counter: 6
Letter: g; Counter: 7
Letter: h; Counter: 8
Letter: i; Counter: 9
Letter: j; Counter: 10


The comment was not meant for snark. You are using a side-effect that may be non-obvious to your future self or folks you share the code with so noting it will help you re-figure out and them figure out what's happening.






share|improve this answer
























  • alright, so I mixed defining a parameter inside the function called counter with updating a counter which was not part of the function. Thank you very much for the detailed explanation.

    – crazysantaclaus
    Nov 23 '18 at 16:43














2












2








2







Let's reduce the complexity of the example:



counter <- 0

invisible(mapply(function(letter, counter) {

counter <- counter + 1
cat("Letter: ", letter, "; Counter: ", counter, "n", sep="")

}, letters[1:10], counter))


NOTE: I only used invisible() to stop printing the result of mapply().



letters[1:10] is a 10-element vector of lower-case letter (built in data).



You define counter outside of mapply(). Unlike for or while, functions in mapply() do not — by default — create or modify variables in the parent scope (outside of mapply(), so the result is this:



Letter: a; Counter: 1
Letter: b; Counter: 1
Letter: c; Counter: 1
Letter: d; Counter: 1
Letter: e; Counter: 1
Letter: f; Counter: 1
Letter: g; Counter: 1
Letter: h; Counter: 1
Letter: i; Counter: 1
Letter: j; Counter: 1


It's fine to pass in a second parameter with info to the function argument of mapply() but if the intent is to have a side-effect of incrementing something outside the scope of the function in mapply() then you really shouldn't pass it to in as parameter and just modify it using the <<- operator, which — according to the help page:



"The operators <<- and ->> are normally only used in functions, and cause a search to be made through parent environments for an existing definition of the variable being assigned. If such a variable is found (and its binding is not locked) then its value is redefined, otherwise assignment takes place in the global environment."



So, we can just do this:



# TO MY FUTURE SELF AND TEAM MEMBERS
# `counter` is modified as a side-effect of operations in the `mapply()`
# that follows the object declaration
counter <- 0

invisible(mapply(function(letter) {

counter <<- counter + 1
cat("Letter: ", letter, "; Counter: ", counter, "n", sep="")

}, letters[1:10]))


to get this:



Letter: a; Counter: 1
Letter: b; Counter: 2
Letter: c; Counter: 3
Letter: d; Counter: 4
Letter: e; Counter: 5
Letter: f; Counter: 6
Letter: g; Counter: 7
Letter: h; Counter: 8
Letter: i; Counter: 9
Letter: j; Counter: 10


The comment was not meant for snark. You are using a side-effect that may be non-obvious to your future self or folks you share the code with so noting it will help you re-figure out and them figure out what's happening.






share|improve this answer













Let's reduce the complexity of the example:



counter <- 0

invisible(mapply(function(letter, counter) {

counter <- counter + 1
cat("Letter: ", letter, "; Counter: ", counter, "n", sep="")

}, letters[1:10], counter))


NOTE: I only used invisible() to stop printing the result of mapply().



letters[1:10] is a 10-element vector of lower-case letter (built in data).



You define counter outside of mapply(). Unlike for or while, functions in mapply() do not — by default — create or modify variables in the parent scope (outside of mapply(), so the result is this:



Letter: a; Counter: 1
Letter: b; Counter: 1
Letter: c; Counter: 1
Letter: d; Counter: 1
Letter: e; Counter: 1
Letter: f; Counter: 1
Letter: g; Counter: 1
Letter: h; Counter: 1
Letter: i; Counter: 1
Letter: j; Counter: 1


It's fine to pass in a second parameter with info to the function argument of mapply() but if the intent is to have a side-effect of incrementing something outside the scope of the function in mapply() then you really shouldn't pass it to in as parameter and just modify it using the <<- operator, which — according to the help page:



"The operators <<- and ->> are normally only used in functions, and cause a search to be made through parent environments for an existing definition of the variable being assigned. If such a variable is found (and its binding is not locked) then its value is redefined, otherwise assignment takes place in the global environment."



So, we can just do this:



# TO MY FUTURE SELF AND TEAM MEMBERS
# `counter` is modified as a side-effect of operations in the `mapply()`
# that follows the object declaration
counter <- 0

invisible(mapply(function(letter) {

counter <<- counter + 1
cat("Letter: ", letter, "; Counter: ", counter, "n", sep="")

}, letters[1:10]))


to get this:



Letter: a; Counter: 1
Letter: b; Counter: 2
Letter: c; Counter: 3
Letter: d; Counter: 4
Letter: e; Counter: 5
Letter: f; Counter: 6
Letter: g; Counter: 7
Letter: h; Counter: 8
Letter: i; Counter: 9
Letter: j; Counter: 10


The comment was not meant for snark. You are using a side-effect that may be non-obvious to your future self or folks you share the code with so noting it will help you re-figure out and them figure out what's happening.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 23 '18 at 15:13









hrbrmstrhrbrmstr

62k694154




62k694154













  • alright, so I mixed defining a parameter inside the function called counter with updating a counter which was not part of the function. Thank you very much for the detailed explanation.

    – crazysantaclaus
    Nov 23 '18 at 16:43



















  • alright, so I mixed defining a parameter inside the function called counter with updating a counter which was not part of the function. Thank you very much for the detailed explanation.

    – crazysantaclaus
    Nov 23 '18 at 16:43

















alright, so I mixed defining a parameter inside the function called counter with updating a counter which was not part of the function. Thank you very much for the detailed explanation.

– crazysantaclaus
Nov 23 '18 at 16:43





alright, so I mixed defining a parameter inside the function called counter with updating a counter which was not part of the function. Thank you very much for the detailed explanation.

– crazysantaclaus
Nov 23 '18 at 16:43




















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%2f53448884%2fuse-a-counter-to-access-named-list-elements-as-ggtitle-within-mapply-call%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







這個網誌中的熱門文章

Xamarin.form Move up view when keyboard appear

Post-Redirect-Get with Spring WebFlux and Thymeleaf

Anylogic : not able to use stopDelay()