programing

문자열로 지정된 식을 평가합니다.

newsource 2023. 6. 19. 21:37

문자열로 지정된 식을 평가합니다.

R이 그것을 사용할 수 있는지 궁금합니다.eval()문자열에 의해 제공되는 계산을 수행하는 함수.

다음은 일반적인 경우입니다.

eval("5+5")

하지만 10 대신 다음과 같은 결과를 얻었습니다.

[1] "5+5"

해결책은?

eval()함수는 식을 평가하지만,"5+5"식이 아니라 문자열입니다.사용하다parse()와 함께text=<string>문자열을 식으로 변경하는 방법

> eval(parse(text="5+5"))
[1] 10
> class("5+5")
[1] "character"
> class(parse(text="5+5"))
[1] "expression"

부르기eval()여러 가지 동작을 유발하며, 일부 동작은 즉시 명확하지 않습니다.

> class(eval(parse(text="5+5")))
[1] "numeric"
> class(eval(parse(text="gray")))
[1] "function"
> class(eval(parse(text="blue")))
Error in eval(expr, envir, enclos) : object 'blue' not found

tryCatch도 참조하십시오.

사용할 수 있습니다.parse()문자를 표현식으로 변환하는 함수입니다.구문 분석은 기본적으로 파일을 예상하므로 입력이 텍스트임을 지정해야 합니다.

eval(parse(text="5+5"))

미안하지만 왜 너무 많은 사람들이 끈이 평가될 수 있는 것이라고 생각하는지 이해할 수 없습니다.당신은 정말로 당신의 사고방식을 바꿔야 합니다.한쪽의 문자열과 다른 쪽의 식, 호출, 평가 사이의 모든 연결을 잊습니다.

(가능성이 있는) 유일한 연결은parse(text = ....)그리고 모든 훌륭한 R 프로그래머들은 이것이 표현식(또는 호출)을 구성하는 효율적이거나 안전한 수단이 아니라는 것을 알아야 합니다.에 대해 자세히 알아보기substitute(),quote()그리고 아마도 사용하는 것의 힘.do.call(substitute, ......).

fortunes::fortune("answer is parse")
# If the answer is parse() you should usually rethink the question.
#    -- Thomas Lumley
#       R-help (February 2005)

2017년 12월: 네, 여기 예가 있습니다(댓글에는 적절한 서식이 없습니다).

q5 <- quote(5+5)
str(q5)
# language 5 + 5

e5 <- expression(5+5)
str(e5)
# expression(5 + 5)

그리고 당신이 더 경험을 쌓는다면 당신은 그것을 배울 것입니다.q5이다."call"반면에.e5이다."expression"그리고 그것조차도e5[[1]]와 동일합니다.q5:

identical(q5, e5[[1]])
# [1] TRUE

이를 위해 특별히 두 가지 기본 R 기능을 언급한 사람이 없는 이유는 잘 모르겠습니다.str2lang()그리고.str2expression()다음은 의 변형입니다.parse()하지만 표현을 좀 더 깨끗하게 하는 것 같습니다.

eval(str2lang("5+5"))

# > 10
  
eval(str2expression("5+5"))

# > 10

또한 이것을 시도하는 사람은 누구나 잘못되었다고 주장하는 포스터에 대해 반발하고 싶습니다.저는 파일에 텍스트로 저장된 R 표현식을 읽고 평가하려고 합니다.이러한 기능은 이 사용 사례에 적합합니다.

요즘에는 또한 사용할 수 있습니다.lazy_eval에서 기능.lazyeval꾸러미

> lazyeval::lazy_eval("5+5")
[1] 10

또는 다음을 사용할 수 있습니다.evals내게서pander원시 결과와 함께 출력 및 모든 경고, 오류 및 기타 메시지를 캡처하는 패키지:

> pander::evals("5+5")
[[1]]
$src
[1] "5 + 5"

$result
[1] 10

$output
[1] "[1] 10"

$type
[1] "numeric"

$msg
$msg$messages
NULL

$msg$warnings
NULL

$msg$errors
NULL


$stdout
NULL

attr(,"class")
[1] "evals"

유사하게 사용rlang:

eval(parse_expr("5+5"))

eval과 parse에 대한 우려가 있다는 것에 동의하지만, 만약 그 표현이 문자열에 있다면, 할 수 있는 것은 별로 없어 보입니다.이 평가 구문 분석은 깔끔한 버전 전문가에 의해 글루 패키지에서도 사용됩니다. https://github.com/tidyverse/glue/blob/d47d6c7701f738f8647b951df418cfd5e6a7bf76/R/transformer.R#L1-L12 을 참조하십시오.

아도받 대답진은여의 수락된 입니다.eval(parse(text="5+5"))텍스트 문자열이 신뢰할 수 없는 소스인 경우 보안 문제가 있습니다(예: 상상).user_input = "list.files()"더 나쁜 파일.제거...

한 가지 잠재적 해결 방법은 다음과 같습니다.

이 개념은 식을 평가할 R 환경을 설정하는 것입니다.R에서 'R과 함께 제공되는' 대부분의 함수는 실제로 R 시작 시 자동으로 로드되는 패키지에 있습니다. 예를 들어 'list'.files', 'files' 및 'files' 기능은 'base' 패키지에서 제공됩니다.평가 환경을 빈 환경으로 설정하면 평가할 식을 더 이상 사용할 수 없으므로 악성 코드가 실행되지 않습니다.아래 코드에서는 기본적으로 산술 관련 함수만 포함되며, 그렇지 않으면 사용자가 명시적으로 허용되는 함수를 평가 환경에 제공할 수 있습니다.

eval_text_expression <- function(text_expression, data_list, eval_envir = NULL) {
  # argument checks
  stopifnot(is.character(text_expression) && length(text_expression) == 1)
  stopifnot(is.list(data_list))
  stopifnot(length(data_list) == 0 || (!is.null(names(data_list)) && all(names(data_list) != "")))
  stopifnot(all(!(lapply(data_list, typeof) %in% c('closure', 'builtin'))))
  stopifnot(is.null(eval_envir) || is.environment(eval_envir))
  # default environment for convenience 
  if (is.null(eval_envir)) {
    arithmetic_funcs <- list("+" = `+`, "-" = `-`, "*" = `*`, "/" = `/`, "^" = `^`, "(" = `(`)
    eval_envir = rlang::new_environment(data = arithmetic_funcs, parent = rlang::empty_env())
  }
  # load data objects into evaluation environment, then evaluate expression
  eval_envir <- list2env(data_list, envir = eval_envir)
  eval(parse(text = text_expression, keep.source = FALSE), eval_envir)
}

eval_text_expression("(a+b)^c - d", list(a = 1, b = 2, c = 3, d = 4))
# [1] 23
eval_text_expression("list.files()", list())
# Error in list.files() : could not find function "list.files"
eval_text_expression("list.files()", list(), eval_envir = rlang::new_environment(list("list.files" = list.files)))
# succeeds in listing my files if i explicitly allow it

언급URL : https://stackoverflow.com/questions/1743698/evaluate-expression-given-as-a-string