是否可以全局将na.rm设置为TRUE?
对于像是否可以全局将na.rm设置为TRUE?,r,na,na.rm,R,Na,Na.rm,对于像max这样的命令,选项na.rm默认设置为FALSE。我理解为什么总的来说这是一个好主意,但我想在一段时间内可逆地关闭它——即在一个会话期间 无论何时作为选项,我如何要求R设置na.rm=TRUE?我发现 options(na.action = na.omit) 但这不起作用。我知道我可以为我编写的每个函数设置一个na.rm=TRUE选项 my.max <- function(x) {max(x, na.rm=TRUE)} my.max一个解决方法(危险)是执行以下操作: 列出所
max
这样的命令,选项na.rm
默认设置为FALSE
。我理解为什么总的来说这是一个好主意,但我想在一段时间内可逆地关闭它——即在一个会话期间
无论何时作为选项,我如何要求R设置na.rm=TRUE
?我发现
options(na.action = na.omit)
但这不起作用。我知道我可以为我编写的每个函数设置一个na.rm=TRUE
选项
my.max <- function(x) {max(x, na.rm=TRUE)}
my.max一个解决方法(危险)是执行以下操作:
列出所有具有na.rm
作为参数的函数。在这里,我将搜索限制在基本包
获取每个函数并在其正文开头添加此行:na.rm=TRUE
将函数分配回基本包
因此,首先我将具有na.rm
作为参数的所有函数存储在一个列表(ll)中:
uses_arg <- function(x,arg)
is.function(fx <- get(x)) &&
arg %in% names(formals(fx))
basevals <- ls(pos="package:base")
na.rm.f <- basevals[sapply(basevals,uses_arg,'na.rm')]
library(purrr)
# Create a vector of function names https://stackoverflow.com/a/17423072/9300556
Funs <- Filter(is.function,sapply(ls(baseenv()),get,baseenv()))
na.rm.f <- names(Filter(function(x) any(names(formals(args(x)))%in% 'na.rm'),Funs))
# Create strings. Dot "." is optional
fs <- lapply(na.rm.f,
function(x) paste0(".", x, "=partial(", x ,", na.rm = T)"))
eval(parse(text = fs))
然后,对于我更改主体的每个函数,代码的灵感来自于data.table
包(FAQ 2.23),它在rbind.data.frame
和cbind.data.frame
的开头添加了一行
ll <- lapply(na.rm.f,function(x)
{
tt <- get(x)
ss = body(tt)
if (class(ss)!="{") ss = as.call(c(as.name("{"), ss))
if(length(ss) < 2) print(x)
else{
if (!length(grep("na.rm = TRUE",ss[[2]],fixed=TRUE))) {
ss = ss[c(1,NA,2:length(ss))]
ss[[2]] = parse(text="na.rm = TRUE")[[1]]
body(tt)=ss
(unlockBinding)(x,baseenv())
assign(x,tt,envir=asNamespace("base"),inherits=FALSE)
lockBinding(x,baseenv())
}
}
})
无法全局地将na.rm
更改为TRUE
。(见Hong Ooi在问题下的评论。)
编辑:
不幸的是,你不想要的答案是唯一有效的答案
通常地对于这一点,没有一个全局选项像
na.action,它只影响建模功能,如lm、glm等
(即使在那里,也不能保证它在所有情况下都能起作用。)商行
Ooi 7月2日13点6分23分
对于我的R包,我重写了现有函数mean
和sum
。感谢大本钟(下面的评论),我将我的功能更改为:
mean <- function(x, ..., na.rm = TRUE) {
base::mean(x, ..., na.rm = na.rm)
}
这将产生sum(c(2,NA,3))=5,而不是NA
sum(c(2,NA,3,NaN))
同样有效。关于在全局范围内更改NA.rm
参数,已经有了一些答案。我只想注意一下purr
或pryr
包中的partial()
函数。使用此函数,您可以使用预定义参数创建现有函数的副本:
library(purrr)
.mean <- partial(mean, na.rm = TRUE)
# Create sample vector
df <- c(1, 2, 3, 4, NA, 6, 7)
mean(df)
>[1] NA
.mean(df)
>[1] 3.833333
现在,在我们的.GlobalEnv
中有.all
、.min
、.max
等。您可以运行它们:
.min(df)
> [1] 1
.max(df)
> [1] 7
.all(df)
> [1] TRUE
要覆盖函数,只需从lappy调用中删除点“.”。
不幸的是,受启发,你不想要的答案是唯一一个普遍有效的答案。没有像na.action那样的全局选项,它只影响建模功能,如lm
,glm
,等等(即使在那里,它也不能保证在所有情况下都有效)。@HongOoi-我认为鉴于你评论中的大量投票,它应该被重新命名为答案(或“the”如果要精确控制省略NAs的位置/时间,另一种方法是在脚本开头包含一个变量,例如do.omit.na=TRUE
,然后在max(x,na.rm=do.omit.na)中使用它
。有人想详细说明一下为什么一般来说设置na.rm=F
是个好主意吗?作为一种向自己表明你计算的总和
/意味着
/etc可能不是你想要的吗?有趣的是,我很欣赏这个答案,我想我理解你在做什么,但我不能投赞成票或接受,因为最新的答案在ss[[2]中给出了错误:下标超出范围
,第一个答案给出max(5,NA)=NA
@Hugh我编辑我的答案。现在你没有错误了。但是,不幸的是,该代码不适用于具有na.rm
参数:“all”“any”“max”“min”“prod”“range”“sum”的基元
函数,或者您可以将其与默认值中的设置默认值
组合使用package@Ben已从CRAN存储库中删除包“默认值”(…)应维修人员的要求,维修人员尚未将其更新为R3.1.0。
使用base::mean(…)
可能比使用mean(…)
要好一点。默认(…)
(如果您决定采用默认方法以外的方法的平均值)。谢谢!请告诉我另一个想法:)我将编辑我的答案。
sum <- function(x, ..., na.rm = TRUE) {
base::sum(x, ..., na.rm = na.rm)
}
library(purrr)
.mean <- partial(mean, na.rm = TRUE)
# Create sample vector
df <- c(1, 2, 3, 4, NA, 6, 7)
mean(df)
>[1] NA
.mean(df)
>[1] 3.833333
library(purrr)
# Create a vector of function names https://stackoverflow.com/a/17423072/9300556
Funs <- Filter(is.function,sapply(ls(baseenv()),get,baseenv()))
na.rm.f <- names(Filter(function(x) any(names(formals(args(x)))%in% 'na.rm'),Funs))
# Create strings. Dot "." is optional
fs <- lapply(na.rm.f,
function(x) paste0(".", x, "=partial(", x ,", na.rm = T)"))
eval(parse(text = fs))
.min(df)
> [1] 1
.max(df)
> [1] 7
.all(df)
> [1] TRUE