计算数据框中 complete/not 变量缺失值的分数,以长格式输出
Calculate fraction of complete/not missing values of variables in a data frame for output in a long format
我有一个包含四个变量的数据框 (df1
),a
、b
、c
和 d
。
我想获得数据框中每个变量的完整性 (!is.na(x)
)。我希望输出为长格式 (df2
)。
问题是我无法让我的代码的 nrow()
部分工作(因此我不知道它是否整体工作)。或者有 dplyr+tidyr 的方法吗?
如有任何帮助,我们将不胜感激。
起点(df1
):
df1 <- data.frame(a=c(1,2,3,NA),b=c(1,2,NA,NA),c=c(1,2,3,4),d=c(NA,NA,NA,NA),stringsAsFactors = TRUE)
当前代码:
sapply(df1, function(x) sum(!is.na(df1$x)) / nrow(df1$x))
期望的结果(df2
):
df2 <- data.frame(nameofvar=c("a","b","c","d"),completeness=c(75,50,100,0))
因为您希望答案采用 长格式 ,方法如下:
df2 = df1 %>%
gather(NameOfVar, Value) %>%
group_by(NameOfVar) %>%
summarize(Completeness = mean(! is.na(Value)) * 100)
至于为什么您的 (base R) 代码不起作用:
当 sapply
遍历 data.frame 时,函数 (x
) 的参数是列数据本身。因此,您现在需要使用 x
而不是 df1$x
1,而现在需要使用 length
,而不是 nrow
,因为每一列 x
都是一个 向量 .
1 此外,$
-用变量子集永远不会起作用,
所以即使 x
是列 name/index,df1$x
也不会起作用。您必须改用 df1[[x]]
。
尝试 purrr
打包 tidyverse
的一部分。
df1 %>%
map_df(~ sum(!is.na(.)) / length(.) * 100)
和data.table
dt1 <- as.data.table(df1)
dt1[, sapply(.SD, function(x) {sum(!is.na(x)) / .N}), .SD = names(dt1)]
或者非常简单地使用 base R:
colSums(!is.na(df1))/ ncol(df1) * 100
仅使用 dplyr
包:
library(dplyr)
df1 <- data.frame(a=c(1,2,3,NA),
b=c(1,2,NA,NA),
c=c(1,2,3,4),
d=c(NA,NA,NA,NA),
stringsAsFactors = TRUE)
# get percentage of non NA values
df1 %>% summarise_all(function(x) mean(! is.na(x)))
# a b c d
# 1 0.75 0.5 1 0
我有一个包含四个变量的数据框 (df1
),a
、b
、c
和 d
。
我想获得数据框中每个变量的完整性 (!is.na(x)
)。我希望输出为长格式 (df2
)。
问题是我无法让我的代码的 nrow()
部分工作(因此我不知道它是否整体工作)。或者有 dplyr+tidyr 的方法吗?
如有任何帮助,我们将不胜感激。
起点(df1
):
df1 <- data.frame(a=c(1,2,3,NA),b=c(1,2,NA,NA),c=c(1,2,3,4),d=c(NA,NA,NA,NA),stringsAsFactors = TRUE)
当前代码:
sapply(df1, function(x) sum(!is.na(df1$x)) / nrow(df1$x))
期望的结果(df2
):
df2 <- data.frame(nameofvar=c("a","b","c","d"),completeness=c(75,50,100,0))
因为您希望答案采用 长格式 ,方法如下:
df2 = df1 %>%
gather(NameOfVar, Value) %>%
group_by(NameOfVar) %>%
summarize(Completeness = mean(! is.na(Value)) * 100)
至于为什么您的 (base R) 代码不起作用:
当 sapply
遍历 data.frame 时,函数 (x
) 的参数是列数据本身。因此,您现在需要使用 x
而不是 df1$x
1,而现在需要使用 length
,而不是 nrow
,因为每一列 x
都是一个 向量 .
1 此外,$
-用变量子集永远不会起作用,
所以即使 x
是列 name/index,df1$x
也不会起作用。您必须改用 df1[[x]]
。
尝试 purrr
打包 tidyverse
的一部分。
df1 %>%
map_df(~ sum(!is.na(.)) / length(.) * 100)
和data.table
dt1 <- as.data.table(df1)
dt1[, sapply(.SD, function(x) {sum(!is.na(x)) / .N}), .SD = names(dt1)]
或者非常简单地使用 base R:
colSums(!is.na(df1))/ ncol(df1) * 100
仅使用 dplyr
包:
library(dplyr)
df1 <- data.frame(a=c(1,2,3,NA),
b=c(1,2,NA,NA),
c=c(1,2,3,4),
d=c(NA,NA,NA,NA),
stringsAsFactors = TRUE)
# get percentage of non NA values
df1 %>% summarise_all(function(x) mean(! is.na(x)))
# a b c d
# 1 0.75 0.5 1 0