计算的均值(或任何其他统计量)省略了零

时间:2019-02-08 18:19:30

标签: r

想象一下,我有一个数据框和一列。如何计算没有零的均值(或任何其他描述性统计量)?也就是说,如果在一列中我有[32,0,0,34,2],我只想拥有[32,34,2]的平均值。

编辑:对如何访问data.table库有什么想法?

4 个答案:

答案 0 :(得分:3)

这是一个更通用的解决方案。 nozero()接受一个函数作为参数,然后使用...将更多参数传递给该函数。

nozero <- function(x, FUN, ...) {
    FUN <- match.fun(FUN)
    FUN(x[x != 0], ...)
}

z <- c(1, 9, 0, 5, 2, 0, 6, 6, 4, 1)

dtf <- data.frame(A=c(2, 5, 0, -2, 1),
                  B=c(-6, 0, 6, 4, 2))

nozero(z, mean)
nozero(z, median)
nozero(z, quantile, 0.25)
nozero(unlist(dtf), quantile, 0.25)

答案 1 :(得分:1)

这是一种purrr方法,说明了几种技术:

library(tidyverse)

set.seed(4)
df <- data.frame(
  A = sample(0:4, 10, replace = TRUE),
  B = sample(0:4, 10, replace = TRUE)
)

df
#>    A B
#> 1  2 3
#> 2  0 1
#> 3  1 0
#> 4  1 4
#> 5  4 2
#> 6  1 2
#> 7  3 4
#> 8  4 2
#> 9  4 4
#> 10 0 3

方法1:显式表示discard()的参数

map_df(df, ~ tibble(
  sum = discard(., . == 0) %>% sum,
  median = discard(., . == 0) %>% median,
  percentile_25 = discard(., . == 0) %>% quantile(probs = 0.25)
), .id = "var")
#> # A tibble: 2 x 4
#>   var     sum median percentile_25
#>   <chr> <int>  <dbl>         <dbl>
#> 1 A        20    2.5             1
#> 2 B        25    3               2

方法2:将参数提取到as_mapper中以创建一个新函数discard_at_zero

discard_at_zero <- as_mapper(~ discard(., . == 0))

map_df(df, ~ tibble(
  sum = discard_at_zero(.) %>% sum,
  median = discard_at_zero(.) %>% median,
  percentile_25 = discard_at_zero(.) %>% quantile(probs = 0.25)
), .id = "var")
#> # A tibble: 2 x 4
#>   var     sum median percentile_25
#>   <chr> <int>  <dbl>         <dbl>
#> 1 A        20    2.5             1
#> 2 B        25    3               2

方法3:概括该参数,以便您可以将其作为第二个值(.y)传递。创建discard_at_value(在下面,我们将元素== 1丢弃)。

discard_at_value <- as_mapper(~ discard(.x, .x == .y))

map_df(df, ~ tibble(
  sum = discard_at_value(., 1) %>% sum,
  median = discard_at_value(., 1) %>% median,
  percentile_25 = discard_at_value(., 1) %>% quantile(probs = 0.25)
), .id = "var")
#> # A tibble: 2 x 4
#>   var     sum median percentile_25
#>   <chr> <int>  <int>         <dbl>
#> 1 A        17      3             1
#> 2 B        24      3             2

方法4::使用purrr::partial预填充我们的discard_at_value函数并创建discard_at_zero2

discard_at_zero2 <- partial(discard_at_value, .y = 0)
map_df(df, ~ tibble(
  sum = discard_at_zero2(.) %>% sum,
  median = discard_at_zero2(.) %>% median,
  percentile_25 = discard_at_zero2(.) %>% quantile(probs = 0.25)
), .id = "var")
#> # A tibble: 2 x 4
#>   var     sum median percentile_25
#>   <chr> <int>  <dbl>         <dbl>
#> 1 A        20    2.5             1
#> 2 B        25    3               2

答案 2 :(得分:0)

如果它是针对每一列的,则只需创建一个函数即可选择您感兴趣的内容,然后将其应用于该函数,并对得到的每个列表进行一次有用的统计:

library(dplyr)
Data<- data.frame(col1= c(0,1,0,3,5),
                  col2 = c(2,4,5,6,0))
NoZero <- function(vec){
  vec <- vec[vec!=0]
  return(vec)
}
Data %>% apply(2, NoZero) %>%lapply(summary)
$`col1`
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
      1       2       3       3       4       5 

$col2
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   2.00    3.50    4.50    4.25    5.25    6.00 

答案 3 :(得分:0)

您可以使用weighted.mean并将非零值的权重设置为1,否则将权重设置为0:

x <- c(32,0,0,34,2)

weighted.mean(x, x != 0)
# [1] 22.66667