我感兴趣的是在R中使用可选参数编写函数的"正确"方法是什么.随着时间的推移,我偶然发现了几条代码在这里采取了不同的路径,我找不到合适的(官方)位置关于这个话题.
到目前为止,我已经写了这样的可选参数:
fooBar <- function(x,y=NULL){
if(!is.null(y)) x <- x+y
return(x)
}
fooBar(3) # 3
fooBar(3,1.5) # 4.5
Run Code Online (Sandbox Code Playgroud)
如果仅x
提供,该函数只返回其参数.它使用NULL
第二个参数的默认值,如果该参数恰好不是NULL
,则该函数会添加两个数字.
或者,可以像这样编写函数(其中第二个参数需要通过名称指定,但也可以使用unlist(z)
或定义z <- sum(...)
):
fooBar <- function(x,...){
z <- list(...)
if(!is.null(z$y)) x <- x+z$y
return(x)
}
fooBar(3) # 3
fooBar(3,y=1.5) # 4.5
Run Code Online (Sandbox Code Playgroud)
我个人更喜欢第一个版本.但是,我可以看到两者的好坏.第一个版本不太容易出错,但第二个版本可用于合并任意数量的选项.
是否有一种"正确"的方式来指定R中的可选参数?到目前为止,我已经确定了第一种方法,但两者偶尔会感觉有点"hacky".
我想编写一个函数,将两种不同的统计方法之一应用于其输入.在这个过程中,我注意到了一些我不理解的不同功能的行为.我想写的函数应该具有以下属性:
基本上,我希望函数的行为与cor
R中的函数类似.在那里,您有一个默认值method = c("pearson", "kendall", "spearman")
,如果method
未指定,则函数计算Pearson相关性.如果用户一次请求多个方法,则该函数返回错误.
从看cor
,这似乎是使用match.arg(method)
.此行为如下所示:
x <- y <- 1:5
cor(x, y, method="pearson")
# = 1
cor(x, y, method="kendall")
# = 1
cor(x, y, method=c("pearson","kendall"))
# gives an error
Run Code Online (Sandbox Code Playgroud)
我尝试编写自己的函数,也使用了match.arg(method)
,但我意识到结果有些不同.即使选择向量method
,函数也不会以错误结束,而是返回第一个方法的结果.
这在这里说明:
myfun <- function(x, method=c("add","multiply")){
method <- match.arg(method)
if(method=="add") return(sum(x))
if(method=="multiply") return(prod(x))
}
x <- 1:5
myfun(x, method="add")
# = 15
myfun(x, method="multiply")
# = 120
myfun(x, method=c("add","multiply"))
# …
Run Code Online (Sandbox Code Playgroud) 假设我在R中有两个包,第一个命名foo
,第二个命名bar
.我希望在一个独立于平台且与CRAN策略一致的方式中包含C函数foo
并共享该功能bar
.
这样做的首选方法是什么,我应该如何使用函数注册和动态库?
我的问题的目的是,即使我阅读了我能找到的所有文件,但我没有发生任何明显的事情,我不确定最可持续的行动方案是什么.
例:
假设在一个包中foo
,我定义了一个C函数addinc
,它增加了两个数字.
#include <R.h>
#include <Rinternals.h>
SEXP addinc(SEXP x_, SEXP y_) {
double x = asReal(x_);
double y = asReal(y_);
double sum = x + y;
return ScalarReal(sum);
}
Run Code Online (Sandbox Code Playgroud)
在同一个包中,我可以尝试调用通过该接口addinc
命名的R函数.addinr
.Call
addinr <- function(x,y){
.Call("addinc", x, y, PACKAGE="foo")
}
Run Code Online (Sandbox Code Playgroud)
但是,在构建,检查和安装软件包时,运行会addinr
返回下面的错误,可能是因为该函数尚未在R中注册.
library(foo)
addinr(1,2)
Run Code Online (Sandbox Code Playgroud)
.Call中的错误("addinc",x,y,PACKAGE ="foo"):
"addinc"对于包"foo"的.Call()不可用
在我看来,解决这个问题的最简单方法是通过添加useDynLib(foo)
到foo
NAMESPACE文件为编译代码构建动态库.这似乎解决了这个问题,因为我现在可以addinr()
毫无问题地打电话.而且,我可以.Call("addinc", ..., PACKAGE="foo")
直接在R内运行.
然而,我的真正问题是,当第二个包bar …
我想编写一个函数来计算数据框中的表达式,但是使用可能包含也可能不包含用户定义对象的表达式来执行此操作.我认为这个神奇的词汇是"非标准的评价",但我还不能理解它.
一个简单的例子(对于我的目的来说还是现实的):说,我想评估lm()
对数据框中找到的变量的调用.
mydf <- data.frame(x=1:10, y=1:10)
Run Code Online (Sandbox Code Playgroud)
这样做的函数可以写成如下:
f <- function(df, expr){
expr <- substitute(expr)
pf <- parent.frame()
eval(expr, df, pf)
}
Run Code Online (Sandbox Code Playgroud)
这样我就可以使用以下命令得到我想要的东西.
f(mydf, lm(y~x))
# Call:
# lm(formula = y ~ x)
#
# Coefficients:
# (Intercept) x
# 1.12e-15 1.00e+00
Run Code Online (Sandbox Code Playgroud)
尼斯.但是,有些情况下,在调用之前将模型方程式保存在对象中会更方便lm()
.不幸的是,上述功能不再适用.
fml <- y~x
f(mydf, lm(fml))
# Error in eval(expr, envir, enclos): object 'y' not found
Run Code Online (Sandbox Code Playgroud)
有人可以解释为什么第二次通话不起作用?如何改变功能,以便两个呼叫都能产生预期的结果?(期望=合身模型)
干杯!
我目前正在编写一个脚本来评估用于线性混合模型的(受限制的)对数似然函数.我需要它来计算模型的可能性,其中一些参数固定为任意值.也许这个脚本对你们中的一些人也有帮助!
我用lmer()
从lme4
和logLik()
来检查我的脚本是否正常工作,因为它应该.而且看起来,它没有!由于我的教育背景并不真正关注这一级别的统计数据,我有点迷失了.
接下来,您将找到一个使用sleepstudy-data的简短示例脚本:
# * * * * * * * * * * * * * * * * * * * * * * * *
# * example data
library(lme4)
data(sleepstudy)
dat <- sleepstudy[ (sleepstudy$Days %in% 0:4) & (sleepstudy$Subject %in% 331:333) ,]
colnames(dat) <- c("y", "x", "group")
mod0 <- lmer( y ~ 1 + x + ( 1 | group ), data = dat)
# + + + + + + …
Run Code Online (Sandbox Code Playgroud) r ×5
evaluation ×2
function ×2
arguments ×1
c ×1
dataframe ×1
expression ×1
lme4 ×1
match ×1
mixed-models ×1
multi-level ×1
object ×1
package ×1
statistics ×1