每个服用na.rm都有pmin和pmax,为什么没有psum?

Mat*_*wle 28 r

似乎R可能缺少一个明显的简单功能:psum.它是以不同的名称存在,还是在某个包中?

x = c(1,3,NA,5)
y = c(2,NA,4,1)

min(x,y,na.rm=TRUE)    # ok
[1] 1
max(x,y,na.rm=TRUE)    # ok
[1] 5
sum(x,y,na.rm=TRUE)    # ok
[1] 16

pmin(x,y,na.rm=TRUE)   # ok
[1] 1 3 4 1
pmax(x,y,na.rm=TRUE)   # ok
[1] 2 3 4 5
psum(x,y,na.rm=TRUE)
[1] 3 3 4 6                             # expected result
Error: could not find function "psum"   # actual result
Run Code Online (Sandbox Code Playgroud)

我意识到这+已经是psum,但是怎么样NA

x+y                      
[1]  3 NA NA  6        # can't supply `na.rm=TRUE` to `+`
Run Code Online (Sandbox Code Playgroud)

有添加的案例psum吗?或者我错过了什么.

这个问题是这个问题的后续问题:在data.table中
使用:=以对R中两列的值求和,忽略NA

Ben*_*ker 16

关注@JoshUlrich对上一个问题的评论,

psum <- function(...,na.rm=FALSE) { 
    rowSums(do.call(cbind,list(...)),na.rm=na.rm) } 
Run Code Online (Sandbox Code Playgroud)

编辑:来自Sven Hohenstein:

psum2 <- function(...,na.rm=FALSE) { 
    dat <- do.call(cbind,list(...))
    res <- rowSums(dat, na.rm=na.rm) 
    idx_na <- !rowSums(!is.na(dat))
    res[idx_na] <- NA
    res 
}

x = c(1,3,NA,5,NA)
y = c(2,NA,4,1,NA)
z = c(1,2,3,4,NA)

psum(x,y,na.rm=TRUE)
## [1] 3 3 4 6 0
psum2(x,y,na.rm=TRUE)
## [1] 3 3 4 6 NA

n = 1e7
x = sample(c(1:10,NA),n,replace=TRUE)
y = sample(c(1:10,NA),n,replace=TRUE)
z = sample(c(1:10,NA),n,replace=TRUE)

library(rbenchmark)
benchmark(psum(x,y,z,na.rm=TRUE),
          psum2(x,y,z,na.rm=TRUE),
          pmin(x,y,z,na.rm=TRUE), 
          pmax(x,y,z,na.rm=TRUE), replications=20)

##                          test replications elapsed relative 
## 4  pmax(x, y, z, na.rm = TRUE)           20  26.114    1.019 
## 3  pmin(x, y, z, na.rm = TRUE)           20  25.632    1.000 
## 2 psum2(x, y, z, na.rm = TRUE)           20 164.476    6.417
## 1  psum(x, y, z, na.rm = TRUE)           20  63.719    2.486
Run Code Online (Sandbox Code Playgroud)

Sven的版本(可以说它是正确的版本)相当慢一些,尽管它是否重要显然取决于应用程序.有人想破解内联/ Rcpp版本吗?

至于为什么这不存在:不知道,但是好运让R-core做出这样的补充......我不能随便想到一个足够广泛的*misc包可以用来......

马修在r-devel上的跟进线程在这里(似乎证实了):
r-devel:pmin和pmax各自服用na.rm,psum怎么样?

  • 刚刚从这个答案检查了`pmin`,`pmax`和`psum`的表演.长度为"1e5","1e3"重复的3个向量和结果非常相似:分别为6.24,6.21,7.55秒.虽然我发现的其他几个版本的"psum"有30个甚至更多. (2认同)
  • 这个`psum`函数是个好主意.只需添加一个:如果所有元素(在向量中的相同位置)都是"NA"(即使"na.rm = TRUE"),"psum"和"pmax"都会返回"NA".检查`pmin(NA,NA,na.rm = TRUE)`.我稍微修改了你的函数来实现`psum`的相同行为:`psum < - function(...,na.rm = FALSE){dat < - do.call(cbind,list(...)); "[< - "(rowSums(dat,na.rm = na.rm),rowSums(is.na(dat))== ncol(dat),NA)}` (2认同)

Sur*_*tel 6

在CRAN上快速搜索后,至少有3个包具有psum功能。rccmiscincadatakitkit似乎是最快的。下面再现了 Ben Bolker 的例子。

benchmark(
  rccmisc::psum(x,y,z,na.rm=TRUE),
  incadata::psum(x,y,z,na.rm=TRUE),
  kit::psum(x,y,z,na.rm=TRUE), 
  psum(x,y,z,na.rm=TRUE),
  psum2(x,y,z,na.rm=TRUE),
  replications=20
)
#                                    test replications elapsed relative
# 2 incadata::psum(x, y, z, na.rm = TRUE)           20   20.05   14.220
# 3      kit::psum(x, y, z, na.rm = TRUE)           20    1.41    1.000
# 4           psum(x, y, z, na.rm = TRUE)           20    8.04    5.702
# 5          psum2(x, y, z, na.rm = TRUE)           20   20.44   14.496
# 1  rccmisc::psum(x, y, z, na.rm = TRUE)           20   23.24   16.482
Run Code Online (Sandbox Code Playgroud)