Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combine dataframes for means and sd's into one dataframe with sd in brackets after the mean

I would like to create a data frame with several different columns containing means, after which the sd is shown in brackets. To give an example:

df <- iris

mean <- aggregate(df[,1:4], list(iris$Species), mean)
sd <- aggregate(df[,1:4], list(iris$Species), sd)

view(mean)
     Group.1 Sepal.Length Sepal.Width Petal.Length Petal.Width
1     setosa        5.006       3.428        1.462       0.246
2 versicolor        5.936       2.770        4.260       1.326
3  virginica        6.588       2.974        5.552       2.026

view(sd)
     Group.1 Sepal.Length Sepal.Width Petal.Length Petal.Width
1     setosa    0.3524897   0.3790644    0.1736640   0.1053856
2 versicolor    0.5161711   0.3137983    0.4699110   0.1977527
3  virginica    0.6358796   0.3224966    0.5518947   0.2746501

Now I would like to have something like this:

    Group.1 Sepal.Length Sepal.Width Petal.Length Petal.Width
1     setosa    5.0 (0.35)   3.4 (0.38)   1.5 (0.17)  0.2 (0.11)
2 versicolor    5.9 (0.52)   2.8 (0.31)   4.3 (0.47)  1.3 (0.20)
3  virginica    6.6 (0.64)   3.0 (0.32)   5.6 (0.55)  2.0 (0.27)

I reckon there should be a way using the paste function, but I can't figure out how.

like image 339
BWolk Avatar asked Mar 15 '19 10:03

BWolk


2 Answers

We can convert the data to matrix and apply paste directly

 dfN <- mean
 dfN[-1] <- paste0(round(as.matrix(mean[-1]), 1), " (", 
              round(as.matrix(sd[-1]), 2), ")")

Also, this can be done in one step instead of creating multiple datasets

 library(dplyr)
 library(stringr)
 df %>%
   group_by(Species) %>% 
   summarise_all(list(~ str_c(round(mean(.), 2), " (", round(sd(.), 2), ")")))
# A tibble: 3 x 5
#  Species    Sepal.Length Sepal.Width Petal.Length Petal.Width
#  <fct>      <chr>        <chr>       <chr>        <chr>      
#1 setosa     5.01 (0.35)  3.43 (0.38) 1.46 (0.17)  0.25 (0.11)
#2 versicolor 5.94 (0.52)  2.77 (0.31) 4.26 (0.47)  1.33 (0.2) 
#3 virginica  6.59 (0.64)  2.97 (0.32) 5.55 (0.55)  2.03 (0.27)
like image 90
akrun Avatar answered Sep 30 '22 07:09

akrun


Using mapply we can paste the values.

df1 <- sd
df1[-1] <- mapply(function(x, y) paste0(x, "(", y, ")"), mean[-1], sd[-1])

df1
#     Group.1 Sepal.Length Sepal.Width Petal.Length Petal.Width
#1     setosa   5.01(0.35)  3.43(0.38)   1.46(0.17)  0.25(0.11)
#2 versicolor   5.94(0.52)  2.77(0.31)   4.26(0.47)   1.33(0.2)
#3  virginica   6.59(0.64)  2.97(0.32)   5.55(0.55)  2.03(0.27)

Better to use different names for your variables than mean and sd since those are functions in R.

like image 38
Ronak Shah Avatar answered Sep 30 '22 09:09

Ronak Shah