Search code examples
rapplytibbler-rownames

How can I get row names from the apply() function's output?


I'm learning R and have a tibble with some World Bank data. I used the apply() function in a slice of the columns and applied the standard deviation over the values, in this way: result <- apply(df[6:46],2,sd,na.rm=TRUE).

The result is an object with two columns with no header, one column is all the names of the tibble columns that were selected and the other one is the standard deviation for each column. When I use the typeof() command in the output, the result is 'double'. The R documentation says the output of apply() is a vector, an array or a list.

I need to know this because I want to extract all the row names and using the command rownames(result) throws the output NULL. What can I do to extract the row names of this object?

enter image description here

Tried rownames(result) and row.names(result and none worked.


Solution

  • Here, the sd returns a single value and as the apply is with MARGIN = 2 i,e columnwise, we are getting a named vector. So, names(out) would get the names instead of row.names. Using a reproducible example with the inbuilt dataset iris

    data(iris)
    out <- apply(iris[1:4], 2, sd, na.rm = TRUE)
    names(out)
    #[1] "Sepal.Length" "Sepal.Width"  "Petal.Length" "Petal.Width" 
    

    Also, by wrapping the output of apply with data.frame, we can use the row.names

    out1 <- data.frame(val = out)
    row.names(out1)
    #[1] "Sepal.Length" "Sepal.Width"  "Petal.Length" "Petal.Width" 
    

    If we need a data.frame as output, this can he directly created with data.frame call

    data.frame(names = names(out), values = out)
    

    Also, this can be done in tidyverse

    library(dplyr)
    library(tidyr)
    iris %>%
         summarise_if(is.numeric, sd, na.rm = TRUE) %>%
         gather
    #     key     value
    #1 Sepal.Length 0.8280661
    #2  Sepal.Width 0.4358663
    #3 Petal.Length 1.7652982
    #4  Petal.Width 0.7622377
    

    Or convert to a list and enframe

    library(tibble)
    iris %>%
        summarise_if(is.numeric, sd, na.rm = TRUE) %>%
        as.list %>% 
        enframe