如何获得按一个变量分组的数据框(或矩阵)所有值的总和的标准差

how to get standard deviation of an aggregate of all values of a dataframe (or matrix), grouped by one variable

我有一个包含 13 列的数据框。第 13 列显示每行所属的组号。我想对每组的行取第 3 到 12 列所有行中所有值的标准差。

 for(i in 1: groupnumber) {  
sd.vect[i] <- sd(as.vector(df[df$group==i,][,-c(1,2,13)]))}

我收到错误

Error in is.data.frame(x) : 'list' object cannot be coerced to type 'double'

如何获取每个组中所有值的标准差?

mtcars为例,

aggregate(.~cyl, data=mtcars, FUN=sd)
#   cyl      mpg     disp       hp      drat        wt     qsec        vs        am      gear     carb
# 1   4 4.509828 26.87159 20.93453 0.3654711 0.5695637 1.682445 0.3015113 0.4670994 0.5393599 0.522233
# 2   6 1.453567 41.56246 24.26049 0.4760552 0.3563455 1.706866 0.5345225 0.5345225 0.6900656 1.812654
# 3   8 2.560048 67.77132 50.97689 0.3723618 0.7594047 1.196014 0.0000000 0.3631365 0.7262730 1.556624

你可以使用dplyr。您可以 group_by(grouping_column),然后使用 sd() 函数 summarise()

library(dplyr)

data_frame%>%>group_by(thirteenth_column)%>%summarise(across(-c(1,2), sd))

以 mtcars 为例:

library(dplyr)

mtcars%>%group_by(cyl)%>%summarise(across(everything(), sd))

# A tibble: 3 x 11
    cyl   mpg  disp    hp  drat    wt  qsec    vs    am  gear  carb
  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1     4  4.51  26.9  20.9 0.365 0.570  1.68 0.302 0.467 0.539 0.522
2     6  1.45  41.6  24.3 0.476 0.356  1.71 0.535 0.535 0.690 1.81 
3     8  2.56  67.8  51.0 0.372 0.759  1.20 0     0.363 0.726 1.56 

也就是说,通过一些更正,您的 for 循环可以工作: 您只需确保 return 一个数据框,因为您想要的结果实际上是一个二维对象。查看 iris 数据集的示例:

sd.df<-data.frame()
for(i in unique(iris$Species)) {
        for (j in 1:ncol(iris[-5])){
        sd.df[i,j] <- sd(iris[iris$Species==i,j])
        }
}
sd.df

                  V1        V2        V3        V4
setosa     0.3524897 0.3790644 0.1736640 0.1053856
versicolor 0.5161711 0.3137983 0.4699110 0.1977527
virginica  0.6358796 0.3224966 0.5518947 0.2746501

更新
我从您的评论中了解到您可能想要一些非常奇怪的东西,即通过分组变量对数据进行分组,而不是获取每个子数据框中所有值的聚合的标准差。在这里使用矩阵可能会更好。 为此,您可能需要按分组列中的 unique() 值对数据进行分组,然后对数据框的其余部分(所有值)调用 sd(),如果您将数据框强制为一个矩阵:

library(dplyr)
library(purrr)

map_dbl(unique(mtcars$cyl), ~as.matrix(mtcars%>%
                                           filter(cyl==.x)%>%
                                           select(-cyl))%>%
            sd())%>%
        set_names(., unique(mtcars$cyl))

        6         4         8 
 62.47655  37.54494 118.18945 

你的数据:

map(unique(df[[13]]), ~as.matrix(df%>%
                                   filter(df[[13]]==.x)%>%
                                   select(-c(1,2,13)))%>%
        sd()%>%
        set_names(., unique(df[[13]]))

还有一个更简单的答案,使用基本子集和 split():

map_dbl(split(mtcars[-c(1,2, 10)], mtcars[10]), ~sd(as.matrix(.x)))

        3         4         5 
119.47824  47.97490  98.71733 

您可以对 cur_data() -

中的列进行子集化
library(dplyr)

result <- df %>%
  group_by(group) %>%
  summarise(sd_value = sd(unlist(select(cur_data(), -(1:2)))))

示例使用 mtcars -

mtcars %>%
  group_by(gear) %>%
  summarise(sd_value = sd(unlist(select(cur_data(), -(1:2)))))

#   gear sd_value
#  <dbl>    <dbl>
#1     3    119. 
#2     4     48.0
#3     5     98.7