仅计算 R 中具有多个数据点的行的行均值
calculating row means for only rows that have more than one data point in R
我正在尝试计算行均值以从 3 个评估点创建一个平均变量。我想包括具有 2 个或 3 个测量点的案例,但不包括只有一个测量点的案例。
例如,
> a <- c(1,0,NA,1,NA,0,1,0,NA,0,NA)
> b <- c(1,0,NA,1,0,1,1,1,NA,0,1)
> c <- c(1,NA,NA,0,NA,0,1,1,1,0,0)
> mydata <- data.frame(a,b,c)
> mydata$M <- rowMeans(subset(mydata, select = c(1:3)), na.rm = TRUE)
> mydata$M
当前输出为除具有 3 个 NA 的行之外的所有行生成均值列表:
[1] 1.00 0.00 NaN 0.66 0.00 0.33 1.00 0.66 1.00 0.00 0.50
但是,我想要的输出是:
[1] 1.00 0.00 NaN 0.66 NaN 0.33 1.00 0.66 NaN 0.00 0.50
这样只有至少包含两个数据点的行才会被用来计算平均值,而不是返回单个数据点作为行平均值。
这是一个复杂的规则,我不确定如何定义它。任何帮助,将不胜感激。
(这是一个几千行的数据集,手动做是不可想象的!)
谢谢!
苏菲
你可以用 dplyr
来尝试这样的事情:
library(dplyr)
mydata %>%
mutate(row_mean = ifelse((is.na(a)+is.na(b)+is.na(c)) %in% 2:3, NaN,
rowMeans(.[1:3], na.rm = TRUE)))
结果:
a b c row_mean
1 1 1 1 1.0000000
2 0 0 NA 0.0000000
3 NA NA NA NaN
4 1 1 0 0.6666667
5 NA 0 NA NaN
6 0 1 0 0.3333333
7 1 1 1 1.0000000
8 0 1 1 0.6666667
9 NA NA 1 NaN
10 0 0 0 0.0000000
11 NA 1 0 0.5000000
您可以创建一个函数,根据某些条件对行应用均值。在您的示例中,如果有两个或多个有效测量值,则计算平均值。
a <- c(1,0,NA,1,NA,0,1,0,NA,0,NA)
b <- c(1,0,NA,1,0,1,1,1,NA,0,1)
c <- c(1,NA,NA,0,NA,0,1,1,1,0,0)
mydata <- data.frame(a,b,c)
阅读函数最好由内而外。这将采用向量 x
并查看有多少 not NA。当它对 TRUE/FALSE 值求和 (sum
) 时,它会预先将它们分别变为 1 和 0。然后它执行测试是否有超过 1 个(所以 2 个或更多)值 - 不是 NA。
conditionalMean <- function(x) {
if (sum(!is.na(x)) > 1) {
mean(x, na.rm = TRUE)
} else {
NA
}
}
我们将此函数应用于您的 data.frame
行,如 MARGIN = 1
所示。如果你有一个按列工作的函数,你会使用 MARGIN = 2
。你可以试试看。比较 apply(mydata, MARGIN = 2, FUN = mean, na.rm = TRUE)
和 colMeans(mydata, na.rm = TRUE)
.
apply(mydata, MARGIN = 1, FUN = conditionalMean)
[1] 1.0000000 0.0000000 NA 0.6666667 NA 0.3333333 1.0000000
[8] 0.6666667 NA 0.0000000 0.5000000
我正在尝试计算行均值以从 3 个评估点创建一个平均变量。我想包括具有 2 个或 3 个测量点的案例,但不包括只有一个测量点的案例。
例如,
> a <- c(1,0,NA,1,NA,0,1,0,NA,0,NA)
> b <- c(1,0,NA,1,0,1,1,1,NA,0,1)
> c <- c(1,NA,NA,0,NA,0,1,1,1,0,0)
> mydata <- data.frame(a,b,c)
> mydata$M <- rowMeans(subset(mydata, select = c(1:3)), na.rm = TRUE)
> mydata$M
当前输出为除具有 3 个 NA 的行之外的所有行生成均值列表:
[1] 1.00 0.00 NaN 0.66 0.00 0.33 1.00 0.66 1.00 0.00 0.50
但是,我想要的输出是:
[1] 1.00 0.00 NaN 0.66 NaN 0.33 1.00 0.66 NaN 0.00 0.50
这样只有至少包含两个数据点的行才会被用来计算平均值,而不是返回单个数据点作为行平均值。
这是一个复杂的规则,我不确定如何定义它。任何帮助,将不胜感激。 (这是一个几千行的数据集,手动做是不可想象的!)
谢谢! 苏菲
你可以用 dplyr
来尝试这样的事情:
library(dplyr)
mydata %>%
mutate(row_mean = ifelse((is.na(a)+is.na(b)+is.na(c)) %in% 2:3, NaN,
rowMeans(.[1:3], na.rm = TRUE)))
结果:
a b c row_mean
1 1 1 1 1.0000000
2 0 0 NA 0.0000000
3 NA NA NA NaN
4 1 1 0 0.6666667
5 NA 0 NA NaN
6 0 1 0 0.3333333
7 1 1 1 1.0000000
8 0 1 1 0.6666667
9 NA NA 1 NaN
10 0 0 0 0.0000000
11 NA 1 0 0.5000000
您可以创建一个函数,根据某些条件对行应用均值。在您的示例中,如果有两个或多个有效测量值,则计算平均值。
a <- c(1,0,NA,1,NA,0,1,0,NA,0,NA)
b <- c(1,0,NA,1,0,1,1,1,NA,0,1)
c <- c(1,NA,NA,0,NA,0,1,1,1,0,0)
mydata <- data.frame(a,b,c)
阅读函数最好由内而外。这将采用向量 x
并查看有多少 not NA。当它对 TRUE/FALSE 值求和 (sum
) 时,它会预先将它们分别变为 1 和 0。然后它执行测试是否有超过 1 个(所以 2 个或更多)值 - 不是 NA。
conditionalMean <- function(x) {
if (sum(!is.na(x)) > 1) {
mean(x, na.rm = TRUE)
} else {
NA
}
}
我们将此函数应用于您的 data.frame
行,如 MARGIN = 1
所示。如果你有一个按列工作的函数,你会使用 MARGIN = 2
。你可以试试看。比较 apply(mydata, MARGIN = 2, FUN = mean, na.rm = TRUE)
和 colMeans(mydata, na.rm = TRUE)
.
apply(mydata, MARGIN = 1, FUN = conditionalMean)
[1] 1.0000000 0.0000000 NA 0.6666667 NA 0.3333333 1.0000000
[8] 0.6666667 NA 0.0000000 0.5000000