提问人:jay.sf 提问时间:10/20/2022 最后编辑:jay.sf 更新时间:10/20/2022 访问量:54
如何通过调度方法的调用并与默认值结合?
How to pass through call of dispatched method and combine with defaults?
问:
我有一个通用函数,一个相应的默认方法,例如一个公式方法。如果调度了默认方法,则 to 应作为 ibute 返回,而 if 已调度,并且参数应替换为 rmula 参数。此外,还应返回默认值(在这两种方法中),即使用户未显式指定。foo
call
foo.default
attr
foo.formula
X
y
fo
foo.default
它看起来已经不太糟糕了,但到目前为止,我无法将呼叫从 传递到 .foo.formula
foo.default
foo <- function(x, ...) UseMethod('foo')
foo.formula <- function(fo, data, ...) {
.cl <- match.call()
y <- model.response(model.frame(fo, data))
X <- model.matrix(fo, data)
foo.default(X, y, .cl=.cl)
}
foo.default <- function(X, y, bar=FALSE, method='1A', beta=2, ...) {
if (!exists('.cl')) .cl <- match.call()
fa <- formalArgs(foo.default)
m <- match(names(.cl), fa, nomatch=0)
.cl <- c(as.list(.cl), as.list(args(foo.default))[-m])
.cl[[1]] <- as.name('foo')
`attr<-`(lm.fit(X, y)$coefficients, 'call', as.call(.cl))
}
foo(X1, y1)
# (Intercept) hp
# 30.09886054 -0.06822828
# attr(,"call")
# foo(X = X1, y = y1, bar = FALSE, method = "1A", beta = 2,
# ... = , NULL)
foo(mpg ~ hp, mtcars)
# (Intercept) hp
# 30.09886054 -0.06822828
# attr(,"call")
# foo(X = X, y = y, .cl = .cl, bar = FALSE, method = "1A",
# beta = 2, ... = , NULL)
所需输出约为:
foo(X1, y1)
# (Intercept) hp
# 30.09886054 -0.06822828
# attr(,"call")
# foo(X = X1, y = y1, bar = FALSE, method = "1A", beta = 2, ...)
foo(mpg ~ hp, mtcars)
# (Intercept) hp
# 30.09886054 -0.06822828
# attr(,"call")
# foo(fo = mpg ~ hp, data = mtcars, bar = FALSE, method = '1A', beta = 2, ...)
我该怎么做?
数据:
y1 <- c(`Mazda RX4` = 21, `Mazda RX4 Wag` = 21, `Datsun 710` = 22.8,
`Hornet 4 Drive` = 21.4, `Hornet Sportabout` = 18.7, Valiant = 18.1,
`Duster 360` = 14.3, `Merc 240D` = 24.4, `Merc 230` = 22.8, `Merc 280` = 19.2,
`Merc 280C` = 17.8, `Merc 450SE` = 16.4, `Merc 450SL` = 17.3,
`Merc 450SLC` = 15.2, `Cadillac Fleetwood` = 10.4, `Lincoln Continental` = 10.4,
`Chrysler Imperial` = 14.7, `Fiat 128` = 32.4, `Honda Civic` = 30.4,
`Toyota Corolla` = 33.9, `Toyota Corona` = 21.5, `Dodge Challenger` = 15.5,
`AMC Javelin` = 15.2, `Camaro Z28` = 13.3, `Pontiac Firebird` = 19.2,
`Fiat X1-9` = 27.3, `Porsche 914-2` = 26, `Lotus Europa` = 30.4,
`Ford Pantera L` = 15.8, `Ferrari Dino` = 19.7, `Maserati Bora` = 15,
`Volvo 142E` = 21.4)
X1 <- structure(c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 110, 110, 93, 110,
175, 105, 245, 62, 95, 123, 123, 180, 180, 180, 205, 215, 230,
66, 52, 65, 97, 150, 150, 245, 175, 66, 91, 113, 264, 175, 335,
109), dim = c(32L, 2L), dimnames = list(c("Mazda RX4", "Mazda RX4 Wag",
"Datsun 710", "Hornet 4 Drive", "Hornet Sportabout", "Valiant",
"Duster 360", "Merc 240D", "Merc 230", "Merc 280", "Merc 280C",
"Merc 450SE", "Merc 450SL", "Merc 450SLC", "Cadillac Fleetwood",
"Lincoln Continental", "Chrysler Imperial", "Fiat 128", "Honda Civic",
"Toyota Corolla", "Toyota Corona", "Dodge Challenger", "AMC Javelin",
"Camaro Z28", "Pontiac Firebird", "Fiat X1-9", "Porsche 914-2",
"Lotus Europa", "Ford Pantera L", "Ferrari Dino", "Maserati Bora",
"Volvo 142E"), c("(Intercept)", "hp")), assign = 0:1)
答:
1赞
Maurits Evers
10/20/2022
#1
这个怎么样?
foo.default <- function(X, y, bar=FALSE, method='1A', beta=2, ...) {
ell <- list(...)
fa <- Filter(Negate(is.null), as.list(args(foo.default)))
if (!exists('.cl', where = ell)) {
.cl <- as.list(match.call())
m <- match(names(.cl), names(fa), nomatch = 0)
.cl <- c(.cl, fa[-m])
} else {
.cl <- c(as.list(ell$.cl), fa[-c(1, 2)])
}
`attr<-`(lm.fit(X, y)$coefficients, 'call', as.call(.cl))
}
foo(X1, y1)
#(Intercept) hp
#30.09886054 -0.06822828
#attr(,"call")
#foo.default(X = X1, y = y1, bar = FALSE, method = "1A", beta = 2,
# ... = )
foo(mpg ~ hp, mtcars)
#(Intercept) hp
#30.09886054 -0.06822828
#attr(,"call")
#foo.formula(fo = mpg ~ hp, data = mtcars, bar = FALSE, method = "1A",
# beta = 2, ... = )
几点评论:
这里有一点(小的?)尴尬:Inside ,不包括前两个参数和何时首先被调度,在这里是硬编码的。所以我不确定当你引入另一种方法时,这将如何概括,例如.只要替换前两个参数就可以了;如果没有,则需要更多的工作。
else
X
y
foo.default
foo.formula
foo.bar(df, ...)
df
foo.default
我不完全明白从哪里来。我认为这是因为返回在强制时会变成最后一个元素。无论哪种方式,都可以用 删除它。
NULL
as.list(args(foo.default))
args
NULL
NULL
as.list
Filter(Negate(is.null), ...)
我还没有整理省略号的论点。而不是我拿走它,你想要里面.
... =
...
call
评论
1赞
jay.sf
10/20/2022
很好的答案,关键点是哪个很棒。毕竟,报告中实际上并不需要。 最后回来真的很奇怪,但我们可以忍受它。ell <- list(...)
...
call
as.list(args(.))
NULL
评论
= , NULL)
...)
as.list(.cl)
"..."
NULL
args
NULL