计算数据框中每第二列的平均值

Calculate mean of every 2nd column in a dataframe

我想计算数据集中每一第二列的行均值,这意味着: A 列和 B 列、C 列和 D 列、E 列和 F 列的平均值。我的数据如下所示:

|A|B|C|D|E|F|
|-|-|-|-|-|-|
|0|1|1|1|0|1|
|0|0|1|1|0|0|
|1|1|0|0|0|1|
|0|1|1|1|1|1|
|1|1|1|1|0|1|

作为条件,我想包括两个值都应大于 0 以计算平均值:

data$meanAB <-if_else(A > 0 & B > 0, rowMeans(data[,1:2]), 0)

我设法为两列执行此操作,但我想要一个解决方案,将新列添加到我的数据框中,每 2 列按行方式添加。 我想以这样的 table 结尾:

|A|B|C|D|E|F|meanAB|meanCD|meanEF|
|-|-|-|-|-|-|-|-|-|
|0|1|1|1|0|1|0|1|0|
|0|0|1|1|0|0|0|1|0|
|1|1|0|0|0|1|1|0|0|
|0|1|1|1|1|1|0|1|1|
|1|1|1|1|0|1|1|1|0|
|0|1|1|1|0|1|0|1|0|
|0|0|1|1|0|0|0|1|0|
|1|1|0|0|0|1|1|0|0|
|0|1|1|1|1|1|0|1|1|
|1|1|1|1|0|1|1|1|0|

提前致谢!

这是一个方法。它使用 cumsum 技巧来两两获取列组。然后循环遍历拆分数据并计算行均值。最后,它将输出与原始输入数据结合起来。

cs <- cumsum(seq_len(ncol(data)) %% 2)
res <- lapply(split(as.list(data), cs), \(x){
  rowMeans(as.data.frame(x))
})
res <- do.call(cbind, res)
colnames(res) <- paste0("mean", tapply(names(data), cs, paste, collapse = ""))
cbind(data, res)
#  A B C D E F meanAB meanCD meanEF
#1 0 1 1 1 0 1    0.5      1    0.5
#2 0 0 1 1 0 0    0.0      1    0.0
#3 1 1 0 0 0 1    1.0      0    0.5
#4 0 1 1 1 1 1    0.5      1    1.0
#5 1 1 1 1 0 1    1.0      1    0.5

dput 格式的数据

data <-
structure(list(A = c(0L, 0L, 1L, 0L, 1L), B = c(1L, 0L, 1L, 1L, 
1L), C = c(1L, 1L, 0L, 1L, 1L), D = c(1L, 1L, 0L, 1L, 1L), E = c(0L, 
0L, 0L, 1L, 0L), F = c(1L, 0L, 1L, 1L, 1L)), row.names = c(NA, 
-5L), class = "data.frame")

Base R 选项使用 split.default -

cbind(df, sapply(split.default(df, ceiling(seq_along(df)/2)), function(x) {
  ifelse(x[1] > 0 & x[2] > 0, rowMeans(x), 0)
}))

#  A B C D E F 1 2 3
#1 0 1 1 1 0 1 0 1 0
#2 0 0 1 1 0 0 0 1 0
#3 1 1 0 0 0 1 1 0 0
#4 0 1 1 1 1 1 0 1 1
#5 1 1 1 1 0 1 1 1 0

其中第 1 列是 A 和 B 的平均值,第 2 列是 C 和 D 的平均值,依此类推。

一个tidyverse解决方案是。对我来说,这非常简短。

library(dplyr)
#> 
#> Attache Paket: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union

data <-
  structure(
    list(
      A = c(0L, 0L, 1L, 0L, 1L),
      B = c(1L, 0L, 1L, 1L, 1L),
      C = c(1L, 1L, 0L, 1L, 1L),
      D = c(1L, 1L, 0L, 1L, 1L),
      E = c(0L, 0L, 0L, 1L, 0L),
      F = c(1L, 0L, 1L, 1L, 1L)
    ),
    row.names = c(NA, -5L),
    class = "data.frame"
  )

data %>%
  rowwise() %>%
  mutate(meanAB = mean(c(A, B)),
         meanCD = mean(c(C, D)),
         meanEF = mean(c(E, F)))
#> # A tibble: 5 x 9
#> # Rowwise: 
#>       A     B     C     D     E     F meanAB meanCD meanEF
#>   <int> <int> <int> <int> <int> <int>  <dbl>  <dbl>  <dbl>
#> 1     0     1     1     1     0     1    0.5      1    0.5
#> 2     0     0     1     1     0     0    0        1    0  
#> 3     1     1     0     0     0     1    1        0    0.5
#> 4     0     1     1     1     1     1    0.5      1    1  
#> 5     1     1     1     1     0     1    1        1    0.5

reprex package (v2.0.1)

于 2021-10-27 创建

我们可以使用

data[paste0('mean', 1:3)] <-  sapply(split.default(df, as.integer(gl(ncol(df), 
      2, ncol(df)))), function(x) {
     i1 <- rowSums(x > 0) == 2
   replace(rowMeans(x), !i1, 0)})