似乎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怎么样?
在CRAN上快速搜索后,至少有3个包具有psum
功能。rccmisc
,incadata
和kit
。kit
似乎是最快的。下面再现了 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)