计算数据框中每第二列的平均值
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)})
我想计算数据集中每一第二列的行均值,这意味着: 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)})