短い例。私はさまざまな "specs"、f(spec)
でテストすることによって、関数の動作を探求しています。私は手で1つのスペックを書きました、spec1
、それにバリエーションとして新しいスペックを作成しています。これを行うために、私は関数を書くことにしました:str(res1)
ためRのクリーンでシンプルなファクトリファクトリR
spec1 = list(fy = list(a = 1), fx = list(f1 = function(x) 10-x, f2 = function(x) 2-x))
make_spec = function(f = function(x) 10-x, xtheta = 2)
list(fy = list(a = 1), fx = list(f1 = f, f2 = function(x) xtheta-x))
res1 = make_spec()
# first problem: they don't match
all.equal(res1,spec1)
# [1] "Component “fx”: Component “f2”: target, current do not match when deparsed"
#^this happens, even though...
res1$fx$f2(4) == spec1$fx$f2(4)
# TRUE
# second problem: res1 is fugly
res1
# $fy
# $fy$a
# [1] 1
#
#
# $fx
# $fx$f1
# function (x)
# 10 - x
# <environment: 0x000000000f8f2e20>
#
# $fx$f2
# function (x)
# xtheta - x
# <environment: 0x000000000f8f2e20>
str(res1)
# even worse
make_spec
のための私の目標です...
all.equal(spec1, res1)
および/またはidentical(spec1, res1)
- を人間が読めるように(無
<environment: ptr>
タグまたはsrcfilecopy
) - 避けてください
substitute
とeval
可能であれば、それは重要です(優先度は高くない) の第二引数を書き出す避けるために、
- (以下「フル」の例を参照してください)
は、これらの目標の一部または全部を達成するための慣用的な方法はありますか?
完全な例。上記の例では、完全に私のユースケースをカバーする場合私はので、ここで後者だ、わからない:
spec0 = list(
v_dist = list(
pdf = function(x) 1,
cdf = function(x) x,
q = function(x) x,
supp = c(0,1)
)
,
ucondv_dist = {
ucondv_dist = list()
ucondv_dist$condmean = function(v) 10-v
ucondv_dist$pdf = function(u,v) dnorm(u, ucondv_dist$condmean(v), 50)
ucondv_dist$cdf = function(u,v) pnorm(u, ucondv_dist$condmean(v), 50)
ucondv_dist
}
)
make_spec = function(ycondx_condmean = function(x) 10-x, ycondx_sd = 50){
s = substitute(list(
x_dist = list(
pdf = function(x) 1,
cdf = function(x) x,
q = function(x) x,
supp = c(0,1)
)
,
ycondx_dist = {
ycondx_dist = list()
ycondx_dist$condmean = ycondx_condmean
ycondx_dist$pdf = function(u,v) dnorm(u, ycondx_dist$condmean(v), ycondx_sd)
ycondx_dist$cdf = function(u,v) pnorm(u, ycondx_dist$condmean(v), ycondx_sd)
ycondx_dist
}
)
, list(ycondx_condmean=ycondx_condmean, ycondx_sd = ycondx_sd))
eval(s, .GlobalEnv)
}
res0 = make_spec()
サイドノート。私はコンピューターファインダーではないので、ここでは「関数ファクトリー」が正しい用語であるかどうかはわかりませんが、関連性があるようです。私は見つけたa paragraph on the concept related to R。
は実際に、それはあなただけのRを好きではないし、本当に、おそらく別の言語、スカラ座やアーランを探しています表示されます。.. 'str'機能はかなり複雑ですが、あなたは確かにそれを書き換えるために歓迎されています。それは、合理的なSOの質問よりもはるかに大きなプロジェクトです。 'eval'と' substitute'を使わずに言語をプログラムしようとする考えは、逆転してどこでも正当化されているようです。 –
@ 42-フィードバックありがとうございます。さて、私の優先順位のリストでは、「eval」と「substitute」を避けることはできませんが、私はそれらを避ける方法を愚かに見落としているだけです。 – Frank
'ライブラリ(pryr)'、 'res1 $ fx -lapply(res1 $ fx、unenclose)'、 'all.equal(res1、spec1) 'を使ってパート1を得ることができます(単なる関数を返すので不器用です) ' – Chris