Доступ к аргументу «данные» функции with()?
Вопрос
Возможно ли, в expr
выражение with()
функция, чтобы получить доступ к data
аргументировать напрямую?Вот что я имею в виду концептуально:
> print(df)
result qid f1 f2 f3
1 -1 1 0.0000 0.1253 0.0000
2 -1 1 0.0098 0.0000 0.0000
3 1 1 0.0000 0.0000 0.1941
4 -1 2 0.0000 0.2863 0.0948
5 1 2 0.0000 0.0000 0.0000
6 1 2 0.0000 0.7282 0.9087
> with(df, subset(.data, select=f1:f3)) # Doesn't work
Конечно, приведенный выше пример немного глуп, но он был бы удобен для таких вещей:
with(subset(df, f2>0), foo(qid, vars=subset(.data, select=f1:f3)))
Я пытался поковыряться с environment()
и parent.frame()
и т. д., но не придумал ничего, что работало.
Возможно, это действительно вопрос о eval()
, поскольку именно так with.default()
реализован.
Решение
С использованием parent.frame()
:
# sample data:
set.seed(2436502)
dfrm <- data.frame(x1 = rnorm(100), x2 = rnorm(100), g1 = sample(letters, 100, TRUE))
# how to use it:
with(subset(dfrm, x1<0), {
str(parent.frame(2)$data)
"Hello!"
})
# 'data.frame': 47 obs. of 3 variables:
# $ x1: num -0.836 -0.343 -0.341 -1.044 -0.665 ...
# $ x2: num 0.362 0.727 0.62 -0.178 -1.538 ...
# $ g1: Factor w/ 26 levels "a","b","c","d",..: 11 4 15 19 8 13 22 15 15 23 ...
Как работает магия
С использованием ls()
вы можете проверить parent.frames
:
with(subset(dfrm, x1<0), {
print(ls())
print(ls(parent.frame(1)))
print(ls(parent.frame(2)))
print(ls(parent.frame(3)))
})
# [1] "g1" "x1" "x2"
# [1] "enclos" "envir" "expr"
# [1] "data" "expr"
# [1] "dfrm"
Как вы видете:
parent.frame(3)
это базовая среда (в данном случае),parent.frame(2)
является средойsubset
функцияparent.frame(1)
является средой{
функция (см.?Paren
)
Другие советы
Я склонен инвертировать его, т.е.положить with()
снаружи и иметь subset()
работать с его данными:
R> data(mtcars)
R> with(subset(mtcars, gear==4), lm(mpg ~ wt)) # no data arg
Call:
lm(formula = mpg ~ wt)
Coefficients:
(Intercept) wt
42.49 -6.86
Это также глупый пример, потому что lm(mpg ~ wt, data=mtcars, subset=gear==4)
очевидно, делает то же самое, но вы уловили суть.