在 R 中使用 for 循环替换列的平均值
Replace mean of the column using for loop in R
我有一个包含五十个问题(Q1 到 Q50)的数据集。这道题的取值为从1到5的李克特量表数据。但是在我的数据集中我有一些缺失值所以我想用它的列平均值替换缺失值。这是单列的示例代码
demodata$Q1 = ifelse(is.na(demodata$Q1),
ave(demodata$Q1, FUN = function(x)mean(x, na.rm = TRUE)),
demodata$Q1)
现在的问题是我的数据集中有大约 50 个问题。所以每次都执行相同的操作非常困难。我如何使用 for 循环或任何简单的技术来管理它?
不确定你为什么要用 ave
做这些事情。这应该足够了,但不一定是最好的方法:
for (n in names(demodata)) {
demodata[[n]] <- ifelse(is.na(demodata[[n]]), mean(demodata[n]], na.rm = TRUE), demodata[[n]])
}
如果您的整个数据集都是问题答案,您可以执行以下操作:
# generate some fake data
demodata <- as.data.frame(replicate(50, sample(c(1:5,NA), 20, replace = TRUE)))
names(demodata) <- paste0("Q",1:50)
library(tidyverse)
ave_data <- demodata %>%
mutate_all(~ replace_na(., mean(., na.rm = TRUE)))
当然,您可能有一些标识符等不需要这样做的地方。以下版本仅将更改应用于那些以 'Q':
开头的变量
ave_data <- demodata %>%
mutate_at(vars(starts_with("Q")),
~ replace_na(., mean(., na.rm = TRUE))
)
考虑 sapply
,重新分配所有列:
demo_data[] <- sapply(demo_data, function(col) {
col[is.na(col)] <- mean(col, na.rm=TRUE)
return(col)
})
测试数据(随机化和种子化)
# BUILD DATAFRAME OF 50 VARS AND 50 OBS
set.seed(5152018)
demo_data <- setNames(data.frame(replicate(50, replicate(50, sample(1:5, 1, replace=TRUE)))),
paste0("Q", 1:50))
# RANDOMLY ASSIGN NAs TO 5 ROWS PER COLUMN (SIMILARLY USED FOR ABOVE SOLUTION)
demo_data[] <- sapply(demo_data, function(col) {
col[sample(seq_along(demo_data), 5, replace=TRUE)] <- NA
return(col)
})
可以使用 zoo
中的 na.aggregate
来完成,默认情况下使用 mean
替换 NA 值
library(zoo)
na.aggregate(demodata)
数据
demodata <- data.frame(col1 = c(1, 2, 3, 4, NA),
col2 = c(6, 7, NA, 8, 9),
col3 = c(8, 10, 11, NA, 12))
我有一个包含五十个问题(Q1 到 Q50)的数据集。这道题的取值为从1到5的李克特量表数据。但是在我的数据集中我有一些缺失值所以我想用它的列平均值替换缺失值。这是单列的示例代码
demodata$Q1 = ifelse(is.na(demodata$Q1),
ave(demodata$Q1, FUN = function(x)mean(x, na.rm = TRUE)),
demodata$Q1)
现在的问题是我的数据集中有大约 50 个问题。所以每次都执行相同的操作非常困难。我如何使用 for 循环或任何简单的技术来管理它?
不确定你为什么要用 ave
做这些事情。这应该足够了,但不一定是最好的方法:
for (n in names(demodata)) {
demodata[[n]] <- ifelse(is.na(demodata[[n]]), mean(demodata[n]], na.rm = TRUE), demodata[[n]])
}
如果您的整个数据集都是问题答案,您可以执行以下操作:
# generate some fake data
demodata <- as.data.frame(replicate(50, sample(c(1:5,NA), 20, replace = TRUE)))
names(demodata) <- paste0("Q",1:50)
library(tidyverse)
ave_data <- demodata %>%
mutate_all(~ replace_na(., mean(., na.rm = TRUE)))
当然,您可能有一些标识符等不需要这样做的地方。以下版本仅将更改应用于那些以 'Q':
开头的变量ave_data <- demodata %>%
mutate_at(vars(starts_with("Q")),
~ replace_na(., mean(., na.rm = TRUE))
)
考虑 sapply
,重新分配所有列:
demo_data[] <- sapply(demo_data, function(col) {
col[is.na(col)] <- mean(col, na.rm=TRUE)
return(col)
})
测试数据(随机化和种子化)
# BUILD DATAFRAME OF 50 VARS AND 50 OBS
set.seed(5152018)
demo_data <- setNames(data.frame(replicate(50, replicate(50, sample(1:5, 1, replace=TRUE)))),
paste0("Q", 1:50))
# RANDOMLY ASSIGN NAs TO 5 ROWS PER COLUMN (SIMILARLY USED FOR ABOVE SOLUTION)
demo_data[] <- sapply(demo_data, function(col) {
col[sample(seq_along(demo_data), 5, replace=TRUE)] <- NA
return(col)
})
可以使用 zoo
中的 na.aggregate
来完成,默认情况下使用 mean
替换 NA 值
library(zoo)
na.aggregate(demodata)
数据
demodata <- data.frame(col1 = c(1, 2, 3, 4, NA),
col2 = c(6, 7, NA, 8, 9),
col3 = c(8, 10, 11, NA, 12))