【问题标题】:Getting column-wise means and standard deviations for positive and negative values separately in R在R中分别获取正值和负值的按列均值和标准差
【发布时间】:2020-12-18 14:25:42
【问题描述】:

我可以按如下方式获得数据帧的按列均值和标准差(样本):

means <- apply(df , 2, mean)
sdevs <- apply(df , 2, sd)

但是,我的数据框包含正值和负值,我需要分别获取正值和负值的均值和标准差

输入示例:

COL1 COL2
1    1
2    1
3    1
-1   -1
-5   -1
-9   -1

示例输出:

positive_means = [2,1]
positive_sdevs = [1,0]
negative_means = [-5,-1]
negative_sdevs = [4,0]

我不想构建 for 循环,因为我的数据框包含太多值和列。 谢谢。

【问题讨论】:

  • for 循环本身还不错。这是不好的,或者让我们说可以改进,如果在存在矢量化函数的情况下使用循环,请参阅?colMeans。 ;)

标签: r dataframe


【解决方案1】:

您可以尝试为正值和负值创建一个组,然后使用dplyr 函数进行汇总:

library(dplyr)
#Code
new <- df %>% mutate(group=ifelse(COL1>0&COL2>0,'Pos','Neg')) %>%
  group_by(group) %>% summarise_all(list('mean'=mean,'sd'=sd))

输出:

# A tibble: 2 x 5
  group COL1_mean COL2_mean COL1_sd COL2_sd
  <chr>     <dbl>     <dbl>   <dbl>   <dbl>
1 Neg          -5        -1       4       0
2 Pos           2         1       1       0

使用的一些数据:

#Data
df <- structure(list(COL1 = c(1L, 2L, 3L, -1L, -5L, -9L), COL2 = c(1L, 
1L, 1L, -1L, -1L, -1L)), class = "data.frame", row.names = c(NA, 
-6L))

另一个选项可以使用apply()rowSums()

#Code1
as.data.frame(apply(df[rowSums(df)>0,],2,function(x) {data.frame(Mean=mean(x),SD=sd(x))}))

输出:

  COL1.Mean COL1.SD COL2.Mean COL2.SD
1         2       1         1       0

#Code2
as.data.frame(apply(df[!rowSums(df)>0,],2,function(x) {data.frame(Mean=mean(x),SD=sd(x))}))

输出:

  COL1.Mean COL1.SD COL2.Mean COL2.SD
1        -5       4        -1       0

【讨论】:

    【解决方案2】:

    这是添加到 Duck 出色答案中的另一个基本 R 选项:

    as.data.frame(lapply(df, function(x) c(mean_pos = mean(x[x > 0]), 
                                           mean_neg = mean(x[x <= 0]),
                                           sd_pos   = sd(x[x > 0 ]), 
                                           sd_neg   = sd(x[x <= 0]))))
    #>          COL1 COL2
    #> mean_pos    2    1
    #> mean_neg   -5   -1
    #> sd_pos      1    0
    #> sd_neg      4    0
    

    【讨论】: