作者a78998042a (Benjimin)
看板R_Language
标题[问题] S3函数主、子函数参数继承问题
时间Fri Jul 5 22:31:53 2019
[问题类型]:
程式谘询(我想用R 做某件事情,但是我不知道要怎麽用R 写出来)
[软体熟悉度]:
使用者(已经有用R 做过不少作品)
[问题叙述]:
请教各位先进S3函数的写法!有两个问题。
需要功能:主函数有参数x,并依条件在内部以子函数改变x值,并取代主函数环境的x值
[程式范例]:
# 主函数
test_f = function(x, y, ...){
result = para_reset_f()
rm(list = c('x', 'y'))
attach(result)
return(sum(x, y))
}
# 子函数
para_reset_f = function(x = x, y = y){
if(x > 5) x = 100 else x = x
return(environment())
}
test_f(5, 10)
# 这个程式会造成
# Error in para_reset_f() :
# promise already under evaluation: recursive default
# argument reference or Earlier problems?"
想询问较好的解法
候选解法1.
result = para_reset_f(x = environment()$x, y = environment()$y)
候选解法2.
environment(para_reset_f) = environment()
result = para_reset_f() ## 子函数参数改为全空
网路上的解法是
result = para_reset_f(x. = x, y. = y)
候选1看起来是最乾净的,不过还没有看过有官方函数是这样写的
应该是有其他参数引用的方式?
第二个问题是,我想将子函数的特定参数值取代主函数
所以我在para_reset_f 输出环境
但为了要让他盖过主函数
我先 rm(list = c('x', 'y'))
再 attach(result)
这个写法看来不太健康,想询问是否有比较正确的解法!
谢谢!
[关键字]:
S3、参数继承
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 180.204.236.87 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/R_Language/M.1562337125.A.53D.html
※ 编辑: a78998042a (180.204.236.87 台湾), 07/05/2019 23:57:33
1F:推 clickhere: S3用第一个参数作判别.如果没有,你需要一个default函数 07/06 10:10
2F:→ clickhere: 或是给定,就像解法一.不要给x=x,y=y在param_reset_f中 07/06 10:13
3F:→ clickhere: attach是尽可能避免的函数之一. 07/06 10:14
4F:→ clickhere: 可以在para_reset_f里面直接`assign()`任何env的任何 07/06 10:15
5F:→ clickhere: 变数. assign('x', x, envir = parent.frame()) 07/06 10:15
6F:→ clickhere: return也可以免了, 必尽都要覆写变数了. 07/06 10:17
谢谢c大的说明与信件回复
para_reset_f = function(x, y){
if(x > 5) x <- 100
assign('x', x, envir = parent.frame())
NULL
}
另外想询问,如果 para_reset_f 内部更改一堆参数
然後想要将 para_reset_f 环境内的所有参数输出
有什麽撰写建议吗? 用assign n次
※ 编辑: a78998042a (180.204.236.87 台湾), 07/06/2019 11:47:58
7F:→ celestialgod: ls + assign +for 07/06 11:51
8F:→ clickhere: 另一种做法是把envir当做para_rest_f的参数. 07/06 21:47
9F:→ clickhere: 直接在para_rest_f内用envir$x <- 100 07/06 21:48
test_f = function(x, y, ...){
env = environment()
para_reset_f(x, y, env)
sum(x, y)
}
para_reset_f = function(x, y, env){
with(env, {
if(x > 5){
x <- 100
y <- 500
}})
}
好聪明! 这样还少了assign的步骤
看起来简洁有力,谢谢解说
※ 编辑: a78998042a (180.204.236.87 台湾), 07/07/2019 01:06:42
发现了一个不解的问题
test_f = function(x, y, ...){
para_reset_f(5, 10, environment())
sum(x, y)
}
para_reset_f = function(g, b, env){
with(env, {
if(x > 5){
x = g + b
}})
}
test_f(50, 10)
# rror in eval(substitute(expr), data, enclos = parent.frame()) :
# 找不到物件 'g'
当 para_reset_f 内参数有其他预设参数时,我是找不到这些参数的
不知道是否有人能解惑!
※ 编辑: a78998042a (180.204.236.87 台湾), 07/08/2019 22:48:33
10F:→ clickhere: with是另一个尽可能避免的函数之一. 07/09 08:18