在模拟过程中,我创建了多个具有1,000,000个变量的数据集。但是,这些变量的某些值是NA,在某些情况下甚至所有值都是NA。现在,我想计算变量的所有值的总和,但要获取NA所有值是否为NA。
common sum(x, na.rm=T)或or 的问题sum(na.omit(x))是,如果所有值均为,则返回0 NA。因此,我编写了自己的函数,该函数NA以预期的方式处理:
sumna <- function(x) {
sumna <- NULL
return(ifelse(all(is.na(x)), NA, sum(na.omit(x))))
}
Run Code Online (Sandbox Code Playgroud)
但是,该实现相当慢。
因此,我正在寻找一个实现或预先实现的函数,该函数求和向量的值,如果所有值均为,则省略NA并返回。NANA
提前谢谢了!
在sum_从hablar作为OP希望有相同的行为。因此,无需重新发明轮子
library(hablar)
sum_(c(1:10, NA))
#[1] 55
sum_(c(NA, NA, NA))
#[1] NA
Run Code Online (Sandbox Code Playgroud)
它可以用于tidyverse或data.table
library(dplyr)
df1 %>%
summarise_all(sum_)
Run Code Online (Sandbox Code Playgroud)
但是,如果我们需要更改OP的自定义功能,而不是ifelse,一个更好的选择是if/else
sumna <- function(x) {
if(all(is.na(x))) NA else sum(x, na.rm = TRUE)
}
Run Code Online (Sandbox Code Playgroud)
另外,我们可以使用向量化 colSums
v1 <- colSums(df1, na.rm = TRUE)
v1[colSums(is.na(df1)) == nrow(df1)] <- NA
Run Code Online (Sandbox Code Playgroud)
由于数据集非常庞大,我们还可以利用高效 data.table
library(data.table)
setDT(df1)[, lapply(.SD, sumna)]
Run Code Online (Sandbox Code Playgroud)
或使用 tidyverse
library(tidyverse)
df1 %>%
summarise_all(sumna)
Run Code Online (Sandbox Code Playgroud)
您可以删除所有 NA 并测试长度是否大于 0。
sumna_a <- function(x) {
x <- na.omit(x)
if(length(x)) return(sum(x))
NA
}
#or
sumna_b <- function(x) {
if(length(na.omit(x))) return(sum(x, na.rm = TRUE))
NA
}
Run Code Online (Sandbox Code Playgroud)
我认为在大多数情况下,如果您只是在只有以下sum(x, na.rm = TRUE)情况时使用和测试,那么它应该是有效的:sum==0NA
sumna_c <- function(x) {
ret <- sum(x, na.rm = TRUE)
if(ret == 0 && all(is.na(x))) {NA} else {ret}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
113 次 |
| 最近记录: |