Объединить фреймы данных для средних значений и sd в один фрейм данных с sd в скобках после среднего значения

#r #mean #paste #standard-deviation

#r #среднее #вставить #стандартное отклонение

Вопрос:

Я хотел бы создать фрейм данных с несколькими разными столбцами, содержащими средние значения, после чего sd отображается в скобках. Чтобы привести пример:

 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
  

Теперь я хотел бы иметь что-то вроде этого:

     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)
  

Я считаю, что должен быть способ использовать paste функцию, но я не могу понять, как.

Ответ №1:

Мы можем преобразовать данные в matrix и применить paste напрямую

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

Кроме того, это можно сделать за один шаг вместо создания нескольких наборов данных

  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)
  

Ответ №2:

Используя, mapply мы можем paste значения.

 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)
  

Лучше использовать разные имена для ваших переменных, чем mean и sd , поскольку это функции в R.

Ответ №3:

Я знаю, что это вопрос 6m, но я наткнулся на него, исследуя, что делать с моими собственными данными, я думаю, это тоже вариант 🙂

 df %>%
rstatix::get_summary_stats(show = c("mean", "sd", "median", "iqr")) %>%
    dplyr::mutate_if(is.numeric, round, digits = 2) %>% 
    dplyr::mutate(mean2 = str_glue("{mean} ({sd})"))