Assigning the same column/rownames names to many matrices in For Loop












1















I have a whole bunch of matrices that I want to assign column and row names to based on a column of names that are held in another column (Names) in a dataframe (months) I have.



Each matrix I want to assign names to corresponds to a concatenated "partner" string and metric held here e.g. one of the matrices is called "facebook_Total_Completed_Rentals":



Metrics = c('_Total_Completed_Rentals','_Registered_Completed_rentals',
'_Registered_renters','_New_Registrations')

Partners = c('facebook', 'altrooz', 'adperio', 'snapchat', 'apple', 'google')


I want to loop through these two to assign the names to the matrices in this way to avoid having to manually code out all the colnames and row.names statements:



for(i in 1:length(Metrics)){
for(j in 1:length(Partners)){
temp = paste0(Partners[j],Metrics[i])
colnames(temp)= months$Names[1:(months_cut-1)]
row.names(temp) = months$Names[1:(months_cut-1)]
}
}


But I get the error:



Error in `colnames<-`(`*tmp*`, value = months$Names[1:(months_cut - 1)]) : 
attempt to set 'colnames' on an object with less than two dimensions


Please help










share|improve this question























  • Fundamentally you need to use get to return environment object by name. Try tmp_matrix <- get(temp) inside loop as temp is a character value and not actual matrix object. But ideally, you save all similar structured matrices in a list and not as separate objects and call it by list and its name: list$facebook_Total_Completed_Rentals.

    – Parfait
    Nov 27 '18 at 15:07


















1















I have a whole bunch of matrices that I want to assign column and row names to based on a column of names that are held in another column (Names) in a dataframe (months) I have.



Each matrix I want to assign names to corresponds to a concatenated "partner" string and metric held here e.g. one of the matrices is called "facebook_Total_Completed_Rentals":



Metrics = c('_Total_Completed_Rentals','_Registered_Completed_rentals',
'_Registered_renters','_New_Registrations')

Partners = c('facebook', 'altrooz', 'adperio', 'snapchat', 'apple', 'google')


I want to loop through these two to assign the names to the matrices in this way to avoid having to manually code out all the colnames and row.names statements:



for(i in 1:length(Metrics)){
for(j in 1:length(Partners)){
temp = paste0(Partners[j],Metrics[i])
colnames(temp)= months$Names[1:(months_cut-1)]
row.names(temp) = months$Names[1:(months_cut-1)]
}
}


But I get the error:



Error in `colnames<-`(`*tmp*`, value = months$Names[1:(months_cut - 1)]) : 
attempt to set 'colnames' on an object with less than two dimensions


Please help










share|improve this question























  • Fundamentally you need to use get to return environment object by name. Try tmp_matrix <- get(temp) inside loop as temp is a character value and not actual matrix object. But ideally, you save all similar structured matrices in a list and not as separate objects and call it by list and its name: list$facebook_Total_Completed_Rentals.

    – Parfait
    Nov 27 '18 at 15:07
















1












1








1








I have a whole bunch of matrices that I want to assign column and row names to based on a column of names that are held in another column (Names) in a dataframe (months) I have.



Each matrix I want to assign names to corresponds to a concatenated "partner" string and metric held here e.g. one of the matrices is called "facebook_Total_Completed_Rentals":



Metrics = c('_Total_Completed_Rentals','_Registered_Completed_rentals',
'_Registered_renters','_New_Registrations')

Partners = c('facebook', 'altrooz', 'adperio', 'snapchat', 'apple', 'google')


I want to loop through these two to assign the names to the matrices in this way to avoid having to manually code out all the colnames and row.names statements:



for(i in 1:length(Metrics)){
for(j in 1:length(Partners)){
temp = paste0(Partners[j],Metrics[i])
colnames(temp)= months$Names[1:(months_cut-1)]
row.names(temp) = months$Names[1:(months_cut-1)]
}
}


But I get the error:



Error in `colnames<-`(`*tmp*`, value = months$Names[1:(months_cut - 1)]) : 
attempt to set 'colnames' on an object with less than two dimensions


Please help










share|improve this question














I have a whole bunch of matrices that I want to assign column and row names to based on a column of names that are held in another column (Names) in a dataframe (months) I have.



Each matrix I want to assign names to corresponds to a concatenated "partner" string and metric held here e.g. one of the matrices is called "facebook_Total_Completed_Rentals":



Metrics = c('_Total_Completed_Rentals','_Registered_Completed_rentals',
'_Registered_renters','_New_Registrations')

Partners = c('facebook', 'altrooz', 'adperio', 'snapchat', 'apple', 'google')


I want to loop through these two to assign the names to the matrices in this way to avoid having to manually code out all the colnames and row.names statements:



for(i in 1:length(Metrics)){
for(j in 1:length(Partners)){
temp = paste0(Partners[j],Metrics[i])
colnames(temp)= months$Names[1:(months_cut-1)]
row.names(temp) = months$Names[1:(months_cut-1)]
}
}


But I get the error:



Error in `colnames<-`(`*tmp*`, value = months$Names[1:(months_cut - 1)]) : 
attempt to set 'colnames' on an object with less than two dimensions


Please help







r for-loop names






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 27 '18 at 14:27









KeithKeith

298




298













  • Fundamentally you need to use get to return environment object by name. Try tmp_matrix <- get(temp) inside loop as temp is a character value and not actual matrix object. But ideally, you save all similar structured matrices in a list and not as separate objects and call it by list and its name: list$facebook_Total_Completed_Rentals.

    – Parfait
    Nov 27 '18 at 15:07





















  • Fundamentally you need to use get to return environment object by name. Try tmp_matrix <- get(temp) inside loop as temp is a character value and not actual matrix object. But ideally, you save all similar structured matrices in a list and not as separate objects and call it by list and its name: list$facebook_Total_Completed_Rentals.

    – Parfait
    Nov 27 '18 at 15:07



















Fundamentally you need to use get to return environment object by name. Try tmp_matrix <- get(temp) inside loop as temp is a character value and not actual matrix object. But ideally, you save all similar structured matrices in a list and not as separate objects and call it by list and its name: list$facebook_Total_Completed_Rentals.

– Parfait
Nov 27 '18 at 15:07







Fundamentally you need to use get to return environment object by name. Try tmp_matrix <- get(temp) inside loop as temp is a character value and not actual matrix object. But ideally, you save all similar structured matrices in a list and not as separate objects and call it by list and its name: list$facebook_Total_Completed_Rentals.

– Parfait
Nov 27 '18 at 15:07














2 Answers
2






active

oldest

votes


















1














Consider the following data.frames :



iris_a  <- iris[1:2,]
iris_b <- iris[3:4,]
iris_c <- iris[5:6,]


The clean way to do what you want is to put them in a list and apply changes on it :



rnms <- c("foo","bar")
your_list <- lapply(list(iris_a = iris_a,iris_b = iris_b, iris_c = iris_c), function(x){
rownames(x) <- rnms
x
})


Then if necessary you can extract its elements back to your local environment :



list2env(your_list, environment())
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# foo 5.1 3.5 1.4 0.2 setosa
# bar 4.9 3.0 1.4 0.2 setosa


A bit more compact using tidyverse :



your_list <- map(lst(iris_a, iris_b, iris_c), `rownames<-`, rnms)





share|improve this answer


























  • what if the matrices were in different sizes?

    – M-M
    Nov 27 '18 at 14:52






  • 1





    Then you can't give them the same dimension names.

    – Milan Valášek
    Nov 27 '18 at 14:55






  • 1





    A bit more compact using base: your_list <- lapply(mget(ls(pattern="iris_")), "row.names<-", rnms)

    – Parfait
    Nov 27 '18 at 15:04













  • @Parfait but OP doesn't have a pattern in his real data :)

    – Moody_Mudskipper
    Nov 27 '18 at 15:06






  • 1





    Or use outer: all_matrices <- as.vector(outer(Partners, Metrics, paste0)) and pass in all_matrices into mget.

    – Parfait
    Nov 27 '18 at 15:13



















0














While @Moody's answer is probably the cleaner option, I thought I'd provide code that does what you originally wanted it to do:



Let's create 4 matrices whose names are combinations of 2 elements:



a_1 <- a_2 <- b_1 <- b_2 <- matrix(1:20, ncol = 5)


Vector of row names and column names:



rnames <- paste0("row_", 1:4)
cnames <- paste0("col_", 1:5)


Get the name elements:



x <- c("a", "b")
y <- 1:2


For your loop, you need to realise that temp is just a character string so colnames(temp) will not work. You want to create a string that includes the entire command, parse it as an expression, and then evaluate it:



for (i in x) {
for (j in y) {
temp <- paste(i, j, sep = "_")
eval(parse(text = paste0("dimnames(", temp, ") <- list(rnames, cnames)")))
}
}


Note. dimnames(temp) is quicker than rownames and colnames.






share|improve this answer























    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%2f53501896%2fassigning-the-same-column-rownames-names-to-many-matrices-in-for-loop%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    Consider the following data.frames :



    iris_a  <- iris[1:2,]
    iris_b <- iris[3:4,]
    iris_c <- iris[5:6,]


    The clean way to do what you want is to put them in a list and apply changes on it :



    rnms <- c("foo","bar")
    your_list <- lapply(list(iris_a = iris_a,iris_b = iris_b, iris_c = iris_c), function(x){
    rownames(x) <- rnms
    x
    })


    Then if necessary you can extract its elements back to your local environment :



    list2env(your_list, environment())
    # Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    # foo 5.1 3.5 1.4 0.2 setosa
    # bar 4.9 3.0 1.4 0.2 setosa


    A bit more compact using tidyverse :



    your_list <- map(lst(iris_a, iris_b, iris_c), `rownames<-`, rnms)





    share|improve this answer


























    • what if the matrices were in different sizes?

      – M-M
      Nov 27 '18 at 14:52






    • 1





      Then you can't give them the same dimension names.

      – Milan Valášek
      Nov 27 '18 at 14:55






    • 1





      A bit more compact using base: your_list <- lapply(mget(ls(pattern="iris_")), "row.names<-", rnms)

      – Parfait
      Nov 27 '18 at 15:04













    • @Parfait but OP doesn't have a pattern in his real data :)

      – Moody_Mudskipper
      Nov 27 '18 at 15:06






    • 1





      Or use outer: all_matrices <- as.vector(outer(Partners, Metrics, paste0)) and pass in all_matrices into mget.

      – Parfait
      Nov 27 '18 at 15:13
















    1














    Consider the following data.frames :



    iris_a  <- iris[1:2,]
    iris_b <- iris[3:4,]
    iris_c <- iris[5:6,]


    The clean way to do what you want is to put them in a list and apply changes on it :



    rnms <- c("foo","bar")
    your_list <- lapply(list(iris_a = iris_a,iris_b = iris_b, iris_c = iris_c), function(x){
    rownames(x) <- rnms
    x
    })


    Then if necessary you can extract its elements back to your local environment :



    list2env(your_list, environment())
    # Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    # foo 5.1 3.5 1.4 0.2 setosa
    # bar 4.9 3.0 1.4 0.2 setosa


    A bit more compact using tidyverse :



    your_list <- map(lst(iris_a, iris_b, iris_c), `rownames<-`, rnms)





    share|improve this answer


























    • what if the matrices were in different sizes?

      – M-M
      Nov 27 '18 at 14:52






    • 1





      Then you can't give them the same dimension names.

      – Milan Valášek
      Nov 27 '18 at 14:55






    • 1





      A bit more compact using base: your_list <- lapply(mget(ls(pattern="iris_")), "row.names<-", rnms)

      – Parfait
      Nov 27 '18 at 15:04













    • @Parfait but OP doesn't have a pattern in his real data :)

      – Moody_Mudskipper
      Nov 27 '18 at 15:06






    • 1





      Or use outer: all_matrices <- as.vector(outer(Partners, Metrics, paste0)) and pass in all_matrices into mget.

      – Parfait
      Nov 27 '18 at 15:13














    1












    1








    1







    Consider the following data.frames :



    iris_a  <- iris[1:2,]
    iris_b <- iris[3:4,]
    iris_c <- iris[5:6,]


    The clean way to do what you want is to put them in a list and apply changes on it :



    rnms <- c("foo","bar")
    your_list <- lapply(list(iris_a = iris_a,iris_b = iris_b, iris_c = iris_c), function(x){
    rownames(x) <- rnms
    x
    })


    Then if necessary you can extract its elements back to your local environment :



    list2env(your_list, environment())
    # Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    # foo 5.1 3.5 1.4 0.2 setosa
    # bar 4.9 3.0 1.4 0.2 setosa


    A bit more compact using tidyverse :



    your_list <- map(lst(iris_a, iris_b, iris_c), `rownames<-`, rnms)





    share|improve this answer















    Consider the following data.frames :



    iris_a  <- iris[1:2,]
    iris_b <- iris[3:4,]
    iris_c <- iris[5:6,]


    The clean way to do what you want is to put them in a list and apply changes on it :



    rnms <- c("foo","bar")
    your_list <- lapply(list(iris_a = iris_a,iris_b = iris_b, iris_c = iris_c), function(x){
    rownames(x) <- rnms
    x
    })


    Then if necessary you can extract its elements back to your local environment :



    list2env(your_list, environment())
    # Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    # foo 5.1 3.5 1.4 0.2 setosa
    # bar 4.9 3.0 1.4 0.2 setosa


    A bit more compact using tidyverse :



    your_list <- map(lst(iris_a, iris_b, iris_c), `rownames<-`, rnms)






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 27 '18 at 14:51

























    answered Nov 27 '18 at 14:45









    Moody_MudskipperMoody_Mudskipper

    23.5k33264




    23.5k33264













    • what if the matrices were in different sizes?

      – M-M
      Nov 27 '18 at 14:52






    • 1





      Then you can't give them the same dimension names.

      – Milan Valášek
      Nov 27 '18 at 14:55






    • 1





      A bit more compact using base: your_list <- lapply(mget(ls(pattern="iris_")), "row.names<-", rnms)

      – Parfait
      Nov 27 '18 at 15:04













    • @Parfait but OP doesn't have a pattern in his real data :)

      – Moody_Mudskipper
      Nov 27 '18 at 15:06






    • 1





      Or use outer: all_matrices <- as.vector(outer(Partners, Metrics, paste0)) and pass in all_matrices into mget.

      – Parfait
      Nov 27 '18 at 15:13



















    • what if the matrices were in different sizes?

      – M-M
      Nov 27 '18 at 14:52






    • 1





      Then you can't give them the same dimension names.

      – Milan Valášek
      Nov 27 '18 at 14:55






    • 1





      A bit more compact using base: your_list <- lapply(mget(ls(pattern="iris_")), "row.names<-", rnms)

      – Parfait
      Nov 27 '18 at 15:04













    • @Parfait but OP doesn't have a pattern in his real data :)

      – Moody_Mudskipper
      Nov 27 '18 at 15:06






    • 1





      Or use outer: all_matrices <- as.vector(outer(Partners, Metrics, paste0)) and pass in all_matrices into mget.

      – Parfait
      Nov 27 '18 at 15:13

















    what if the matrices were in different sizes?

    – M-M
    Nov 27 '18 at 14:52





    what if the matrices were in different sizes?

    – M-M
    Nov 27 '18 at 14:52




    1




    1





    Then you can't give them the same dimension names.

    – Milan Valášek
    Nov 27 '18 at 14:55





    Then you can't give them the same dimension names.

    – Milan Valášek
    Nov 27 '18 at 14:55




    1




    1





    A bit more compact using base: your_list <- lapply(mget(ls(pattern="iris_")), "row.names<-", rnms)

    – Parfait
    Nov 27 '18 at 15:04







    A bit more compact using base: your_list <- lapply(mget(ls(pattern="iris_")), "row.names<-", rnms)

    – Parfait
    Nov 27 '18 at 15:04















    @Parfait but OP doesn't have a pattern in his real data :)

    – Moody_Mudskipper
    Nov 27 '18 at 15:06





    @Parfait but OP doesn't have a pattern in his real data :)

    – Moody_Mudskipper
    Nov 27 '18 at 15:06




    1




    1





    Or use outer: all_matrices <- as.vector(outer(Partners, Metrics, paste0)) and pass in all_matrices into mget.

    – Parfait
    Nov 27 '18 at 15:13





    Or use outer: all_matrices <- as.vector(outer(Partners, Metrics, paste0)) and pass in all_matrices into mget.

    – Parfait
    Nov 27 '18 at 15:13













    0














    While @Moody's answer is probably the cleaner option, I thought I'd provide code that does what you originally wanted it to do:



    Let's create 4 matrices whose names are combinations of 2 elements:



    a_1 <- a_2 <- b_1 <- b_2 <- matrix(1:20, ncol = 5)


    Vector of row names and column names:



    rnames <- paste0("row_", 1:4)
    cnames <- paste0("col_", 1:5)


    Get the name elements:



    x <- c("a", "b")
    y <- 1:2


    For your loop, you need to realise that temp is just a character string so colnames(temp) will not work. You want to create a string that includes the entire command, parse it as an expression, and then evaluate it:



    for (i in x) {
    for (j in y) {
    temp <- paste(i, j, sep = "_")
    eval(parse(text = paste0("dimnames(", temp, ") <- list(rnames, cnames)")))
    }
    }


    Note. dimnames(temp) is quicker than rownames and colnames.






    share|improve this answer




























      0














      While @Moody's answer is probably the cleaner option, I thought I'd provide code that does what you originally wanted it to do:



      Let's create 4 matrices whose names are combinations of 2 elements:



      a_1 <- a_2 <- b_1 <- b_2 <- matrix(1:20, ncol = 5)


      Vector of row names and column names:



      rnames <- paste0("row_", 1:4)
      cnames <- paste0("col_", 1:5)


      Get the name elements:



      x <- c("a", "b")
      y <- 1:2


      For your loop, you need to realise that temp is just a character string so colnames(temp) will not work. You want to create a string that includes the entire command, parse it as an expression, and then evaluate it:



      for (i in x) {
      for (j in y) {
      temp <- paste(i, j, sep = "_")
      eval(parse(text = paste0("dimnames(", temp, ") <- list(rnames, cnames)")))
      }
      }


      Note. dimnames(temp) is quicker than rownames and colnames.






      share|improve this answer


























        0












        0








        0







        While @Moody's answer is probably the cleaner option, I thought I'd provide code that does what you originally wanted it to do:



        Let's create 4 matrices whose names are combinations of 2 elements:



        a_1 <- a_2 <- b_1 <- b_2 <- matrix(1:20, ncol = 5)


        Vector of row names and column names:



        rnames <- paste0("row_", 1:4)
        cnames <- paste0("col_", 1:5)


        Get the name elements:



        x <- c("a", "b")
        y <- 1:2


        For your loop, you need to realise that temp is just a character string so colnames(temp) will not work. You want to create a string that includes the entire command, parse it as an expression, and then evaluate it:



        for (i in x) {
        for (j in y) {
        temp <- paste(i, j, sep = "_")
        eval(parse(text = paste0("dimnames(", temp, ") <- list(rnames, cnames)")))
        }
        }


        Note. dimnames(temp) is quicker than rownames and colnames.






        share|improve this answer













        While @Moody's answer is probably the cleaner option, I thought I'd provide code that does what you originally wanted it to do:



        Let's create 4 matrices whose names are combinations of 2 elements:



        a_1 <- a_2 <- b_1 <- b_2 <- matrix(1:20, ncol = 5)


        Vector of row names and column names:



        rnames <- paste0("row_", 1:4)
        cnames <- paste0("col_", 1:5)


        Get the name elements:



        x <- c("a", "b")
        y <- 1:2


        For your loop, you need to realise that temp is just a character string so colnames(temp) will not work. You want to create a string that includes the entire command, parse it as an expression, and then evaluate it:



        for (i in x) {
        for (j in y) {
        temp <- paste(i, j, sep = "_")
        eval(parse(text = paste0("dimnames(", temp, ") <- list(rnames, cnames)")))
        }
        }


        Note. dimnames(temp) is quicker than rownames and colnames.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 27 '18 at 15:01









        Milan ValášekMilan Valášek

        36319




        36319






























            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%2f53501896%2fassigning-the-same-column-rownames-names-to-many-matrices-in-for-loop%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

            Lallio

            Futebolista

            Jornalista