[英]eval(parse(text=x)) inside a function, how to evaluate in global environment?
I'm trying to write a function that generates a vector of strings, each of which are evaluated as expressions in the global environment. 我正在尝试编写一个生成字符串向量的函数,每个函数都被评估为全局环境中的表达式。 The problem is that eval(parse(text=x)) only evaluates inside the function's environment.
问题是eval(parse(text = x))仅在函数环境中进行求值。
As a hypothetical example, say that I want to replace several variables' values with NA, but only if they're below a certain cutoff value. 作为一个假设的例子,假设我想用NA替换几个变量的值,但前提是它们低于某个截止值。
set.seed(200)
df <- as.data.frame(matrix(runif(25), nrow=5, ncol=5))
df
V1 V2 V3 V4 V5
1 0.5337724 0.83929374 0.4543649 0.3072981 0.46036069
2 0.5837650 0.71160009 0.6492529 0.5667674 0.09874701
3 0.5895783 0.09650122 0.1537271 0.1317879 0.20659381
4 0.6910399 0.52382473 0.6492887 0.9221776 0.92233983
5 0.6673315 0.23535054 0.3832137 0.6463296 0.31942681
cutoff.V1 <- 0.9
cutoff.V2 <- 0.5
cutoff.V3 <- 0.1
cutoff.V4 <- 0.7
cutoff.V5 <- 0.4
Rather than copy-and-pasting the same line over and over, changing the same text in each line... 而不是一遍又一遍地复制和粘贴相同的行,改变每行中的相同文本......
df$V1[df$V1 < cutoff.V1] <- NA
df$V2[df$V2 < cutoff.V2] <- NA
df$V3[df$V3 < cutoff.V3] <- NA
df$V4[df$V4 < cutoff.V4] <- NA
df$V5[df$V5 < cutoff.V5] <- NA
# ad infinitum...
...I'm trying to have R do it for me: ......我想让R为我做这件事:
vars <- c("V1", "V2", "V3", "V4", "V5")
variable.queue <- function(vec, placeholder, command) {
x <- vector()
for(i in 1:length(vec)) {
x[i] <- gsub(placeholder, vec[i], command)
}
return(x)
}
commands <- variable.queue(vars, "foo", "df$foo[df$foo < cutoff.foo] <- NA")
for(i in 1:length(commands)) {eval(parse(text=commands[i]))}
df
V1 V2 V3 V4 V5
1 NA 0.8392937 0.4543649 NA 0.4603607
2 NA 0.7116001 0.6492529 NA NA
3 NA NA 0.1537271 NA NA
4 NA 0.5238247 0.6492887 0.9221776 0.9223398
5 NA NA 0.3832137 NA NA
# FYI the object "commands" is the vector of strings that I want evaluated
commands
[1] "df$V1[df$V1 < cutoff.V1] <- NA" "df$V2[df$V2 < cutoff.V2] <- NA" "df$V3[df$V3 < cutoff.V3] <- NA"
[4] "df$V4[df$V4 < cutoff.V4] <- NA" "df$V5[df$V5 < cutoff.V5] <- NA"
This solution works, but I want to put the last for-loop INSIDE the function. 这个解决方案有效,但我想把最后一个for循环INSIDE放在函数中。 Any ideas?
有任何想法吗?
Edit: Thanks, Kevin. 编辑:谢谢,凯文。 Here's the "functional" version (bwahaha, I just can't help myself sometimes):
这是“功能”版本(bwahaha,我有时无法帮助自己):
variable.queue <- function(vec, placeholder, command) {
x <- vector()
for(i in 1:length(vec)) {
x[i] <- gsub(placeholder, vec[i], command)
}
for(i in 1:length(x)) {
eval(parse(text=x[i]), envir= .GlobalEnv)
}
}
variable.queue(vars, "foo", "df$foo[df$foo < cutoff.foo] <- NA")
There has to be a better solution. 必须有一个更好的解决方案。 Eg, for your example, this works:
例如,对于您的示例,这适用:
set.seed(200)
df <- as.data.frame(matrix(runif(25), nrow=5, ncol=5))
cutoff <- c(0.9,0.5,0.1,0.7,0.4)
df[mapply("<", df,cutoff)] <- NA
#or
df[sweep(df,2,cutoff,"<")] <- NA
#or even
df[df < rep(cutoff,each=nrow(df))] <- NA
Which all give: 这一切都给了:
> df
V1 V2 V3 V4 V5
1 NA 0.8392937 0.4543649 NA 0.4603607
2 NA 0.7116001 0.6492529 NA NA
3 NA NA 0.1537271 NA NA
4 NA 0.5238247 0.6492887 0.9221776 0.9223398
5 NA NA 0.3832137 NA NA
eval
has an argument, envir
, that allows you to specify the environment in which you want to evaluate your expression. eval
有一个参数envir
,它允许您指定要在其中评估表达式的环境。 So, 所以,
eval(parse(text=command[i]), envir=.GlobalEnv)
should hopefully work. 应该有希望工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.