按变量分组,然后查找 R 中每列缺失值的比例
Grouping by a variable, then finding proportion of missing values for each column in R
我有一个带有因子变量的数据框和带有几个 NA 的列,如图所示。
var col1 col2 col3
C 1 NA 1
A NA 1 1
C NA NA NA
A 1 NA 1
B NA 1 1
A 1 1 1
B 1 NA 1
B 1 1 1
C NA NA 1
B NA 1 1
我正在寻找一种方法来对变量进行分组并获取每列缺失值的比例,按 'var' 中的水平分组。输出应如下所示:
var col1 col2 col3
A 0.33 0.33 0
B 0.5 0.25 0
C 0.66 1.00 0.33
任何方法都可以,我们将不胜感激,但最好使用简单的 dplyr 方法。谢谢!
编辑: 我正在寻找一种方法,允许我一次对多个列执行此操作,return 一个类似于我的数据框如上所示。
假设我的数据被命名为 'df' 那么,我想一次获得所有列的缺失比例 而不必再次手动输入名称。
以下代码不起作用,但它是我想要实现的目标的总体思路。也许一个功能可以提供帮助,但我不确定我将如何处理它。
df %>% group_by(var) %>% summarise(names(df[,-1]) = sum(is.na(names(df[,-1])))/n())
您可以尝试这样的操作:
# Create some arbitrary matrix
rs <- 100
dat <- data.frame(matrix(1,rs,3))
for(i in 1:rs){
dat[i,sample(1:3,2,)] <- NA
}
dat <- cbind(rep(c("A","B","C"),rs)[1:rs],dat)
colnames(dat)[1] <- "var"
# Use the by function with an apply statement
by(dat[,c("X1","X2","X3")],dat[,"var"],function(x) apply(x,2,function(z){
n <- length(z)
miss <- sum(is.na(z))
prop <- miss/n
}))
假设您的数据在数据框中 data
,您可以执行以下操作:
## Your data:
data <- structure(list(var = structure(c(3L, 1L, 3L, 1L,
2L, 1L, 2L, 2L, 3L, 2L), .Label = c("A", "B", "C"),
class = "factor"), col1 = c(1, NA, NA, 1, NA, 1, 1, 1, NA, NA),
col2 = c(NA, 1, NA, NA, 1, 1, NA, 1, NA, 1),
col3 = c(1, 1, NA, 1, 1, 1, 1, 1, 1, 1)),
.Names = c("var", "col1", "col2", "col3"),
row.names = c(NA, -10L), class = "data.frame")
library(dplyr)
outDf <- data %>% group_by(var) %>%
dplyr::summarise(col1 = sum(is.na(col1))/n(),
col2 = sum(is.na(col2))/n(),
col3 = sum(is.na(col3))/n())
outDf
### A tibble: 3 × 4
## var col1 col2 col3
## <fctr> <dbl> <dbl> <dbl>
##1 A 0.3333333 0.3333333 0.0000000
##2 B 0.5000000 0.2500000 0.0000000
##3 C 0.6666667 1.0000000 0.3333333
编辑:
要一次调用将其应用于所有列,您可以使用:
outDf <- data %>% group_by(var) %>%
dplyr::summarise_all(function(x) sum(is.na(x))/length(x))
outDf
### A tibble: 3 × 4
## var col1 col2 col3
## <fctr> <dbl> <dbl> <dbl>
##1 A 0.3333333 0.3333333 0.0000000
##2 B 0.5000000 0.2500000 0.0000000
##3 C 0.6666667 1.0000000 0.3333333
这是一个更通用的 dplyr
解决方案 summarise_each
,它将接受任意数量的列:
df1 <-read.table(text="var col1 col2 col3
C 1 NA 1
A NA 1 1
C NA NA NA
A 1 NA 1
B NA 1 1
A 1 1 1
B 1 NA 1
B 1 1 1
C NA NA 1
B NA 1 1",header=TRUE, stringsAsFactors=FALSE)
library(dplyr)
df1 %>%
group_by(var) %>%
summarise_each(funs(sum(is.na(.))/length(.)))
# A tibble: 3 × 4
var col1 col2 col3
<chr> <dbl> <dbl> <dbl>
1 A 0.3333333 0.3333333 0.0000000
2 B 0.5000000 0.2500000 0.0000000
3 C 0.6666667 1.0000000 0.3333333
我们也可以用 aggregate
来自 base R
aggregate(.~var, data, FUN = function(x) sum(is.na(x))/length(x), na.action=NULL)
# var col1 col2 col3
#1 A 0.3333333 0.3333333 0.0000000
#2 B 0.5000000 0.2500000 0.0000000
#3 C 0.6666667 1.0000000 0.3333333
或 data.table
library(data.table)
setDT(data)[, lapply(.SD, function(x) sum(is.na(x))/.N), var]
我有一个带有因子变量的数据框和带有几个 NA 的列,如图所示。
var col1 col2 col3
C 1 NA 1
A NA 1 1
C NA NA NA
A 1 NA 1
B NA 1 1
A 1 1 1
B 1 NA 1
B 1 1 1
C NA NA 1
B NA 1 1
我正在寻找一种方法来对变量进行分组并获取每列缺失值的比例,按 'var' 中的水平分组。输出应如下所示:
var col1 col2 col3
A 0.33 0.33 0
B 0.5 0.25 0
C 0.66 1.00 0.33
任何方法都可以,我们将不胜感激,但最好使用简单的 dplyr 方法。谢谢!
编辑: 我正在寻找一种方法,允许我一次对多个列执行此操作,return 一个类似于我的数据框如上所示。
假设我的数据被命名为 'df' 那么,我想一次获得所有列的缺失比例 而不必再次手动输入名称。
以下代码不起作用,但它是我想要实现的目标的总体思路。也许一个功能可以提供帮助,但我不确定我将如何处理它。
df %>% group_by(var) %>% summarise(names(df[,-1]) = sum(is.na(names(df[,-1])))/n())
您可以尝试这样的操作:
# Create some arbitrary matrix
rs <- 100
dat <- data.frame(matrix(1,rs,3))
for(i in 1:rs){
dat[i,sample(1:3,2,)] <- NA
}
dat <- cbind(rep(c("A","B","C"),rs)[1:rs],dat)
colnames(dat)[1] <- "var"
# Use the by function with an apply statement
by(dat[,c("X1","X2","X3")],dat[,"var"],function(x) apply(x,2,function(z){
n <- length(z)
miss <- sum(is.na(z))
prop <- miss/n
}))
假设您的数据在数据框中 data
,您可以执行以下操作:
## Your data:
data <- structure(list(var = structure(c(3L, 1L, 3L, 1L,
2L, 1L, 2L, 2L, 3L, 2L), .Label = c("A", "B", "C"),
class = "factor"), col1 = c(1, NA, NA, 1, NA, 1, 1, 1, NA, NA),
col2 = c(NA, 1, NA, NA, 1, 1, NA, 1, NA, 1),
col3 = c(1, 1, NA, 1, 1, 1, 1, 1, 1, 1)),
.Names = c("var", "col1", "col2", "col3"),
row.names = c(NA, -10L), class = "data.frame")
library(dplyr)
outDf <- data %>% group_by(var) %>%
dplyr::summarise(col1 = sum(is.na(col1))/n(),
col2 = sum(is.na(col2))/n(),
col3 = sum(is.na(col3))/n())
outDf
### A tibble: 3 × 4
## var col1 col2 col3
## <fctr> <dbl> <dbl> <dbl>
##1 A 0.3333333 0.3333333 0.0000000
##2 B 0.5000000 0.2500000 0.0000000
##3 C 0.6666667 1.0000000 0.3333333
编辑: 要一次调用将其应用于所有列,您可以使用:
outDf <- data %>% group_by(var) %>%
dplyr::summarise_all(function(x) sum(is.na(x))/length(x))
outDf
### A tibble: 3 × 4
## var col1 col2 col3
## <fctr> <dbl> <dbl> <dbl>
##1 A 0.3333333 0.3333333 0.0000000
##2 B 0.5000000 0.2500000 0.0000000
##3 C 0.6666667 1.0000000 0.3333333
这是一个更通用的 dplyr
解决方案 summarise_each
,它将接受任意数量的列:
df1 <-read.table(text="var col1 col2 col3
C 1 NA 1
A NA 1 1
C NA NA NA
A 1 NA 1
B NA 1 1
A 1 1 1
B 1 NA 1
B 1 1 1
C NA NA 1
B NA 1 1",header=TRUE, stringsAsFactors=FALSE)
library(dplyr)
df1 %>%
group_by(var) %>%
summarise_each(funs(sum(is.na(.))/length(.)))
# A tibble: 3 × 4
var col1 col2 col3
<chr> <dbl> <dbl> <dbl>
1 A 0.3333333 0.3333333 0.0000000
2 B 0.5000000 0.2500000 0.0000000
3 C 0.6666667 1.0000000 0.3333333
我们也可以用 aggregate
来自 base R
aggregate(.~var, data, FUN = function(x) sum(is.na(x))/length(x), na.action=NULL)
# var col1 col2 col3
#1 A 0.3333333 0.3333333 0.0000000
#2 B 0.5000000 0.2500000 0.0000000
#3 C 0.6666667 1.0000000 0.3333333
或 data.table
library(data.table)
setDT(data)[, lapply(.SD, function(x) sum(is.na(x))/.N), var]