Почему замена заменить текст кавычки на строку в R?

Я хотел ответить на вопрос о plotmath но мне не удалось получить желаемый результат substitute. Мой желаемый результат: paste("Hi", paste(italic(yes),"why not?"))
и что я получаю: paste("Hi", "paste(italic(yes),\"why not?\")")

text<-'paste(italic(yes),"why not?")'
text
[1] "paste(italic(yes),\"why not?\")"
noqoute_text<-noquote(text)
noqoute_text
[1] paste(italic(yes),"why not?")
sub<-substitute(paste("Hi",noqoute_text),
           env=list(noqoute_text=noqoute_text))
sub
paste("Hi", "paste(italic(yes),\"why not?\")")

Ответ 1

Вы используете неправильную функцию, используйте parse вместо noquote:

text<-'paste(italic(yes),"why not?")'
noquote_text <- parse(text=text)[[1]]

sub<- substitute(paste("Hi",noquote_text),env=list(noquote_text= noquote_text))
# paste("Hi", paste(italic(yes), "why not?"))

noquote просто применяет class к объекту character типа с помощью специального метода print чтобы не отображать кавычки.

str(noquote("a"))
Class 'noquote'  chr "a"
unclass(noquote("a"))
[1] "a"

Не могли бы вы уточнить ваш ответ?

В R вы должны быть осторожны с разницей между тем, что находится в объекте, и тем, что напечатано.

Что делает noquote:

  • добавить "noquote" к атрибуту класса объекта
  • Это

Код является:

function (obj) 
{
    if (!inherits(obj, "noquote")) 
        class(obj) <- c(attr(obj, "class"), "noquote")
    obj
}

Затем, когда вы печатаете его, методы print.noquote:

  • Удаляет класс "noquote" из объекта, если он там
  • вызывает print с аргументом quote = FALSE
  • это

Вы также можете вызвать print.noquote для строки:

print.noquote("a")
[1] a

Он печатает так же, как quote(a) или substitute(a), но это совершенно другой зверь.

В коде, который вы пробовали, вы заменяли строку вместо вызова.

Ответ 2

Для решения вопроса я думаю, что ответ Moody_Mudskipperss работает хорошо, но, как вы просили некоторые уточнения...

Вы должны быть осторожны с тем, как похожие вещи на самом деле хранятся в R, что означает, что они ведут себя по-разному.
Особенно с тем, как plotmath обрабатывает метки, так как они пытаются эмулировать то, как обычно обрабатываются character -strings, но затем применяют свои собственные правила. 3 вещи, которые вы смешиваете, я думаю:

  • character() является наиболее знакомым: просто строка. Печать может сбить с толку, когда кавычки и т.д. Функция noquote основном указывает R пометить его как аргумент, чтобы кавычки не экранировались.
  • вызовы являются "неоцененными вызовами функций": это инструкция относительно того, что должен делать R, но он еще не выполнен. Любые ошибки в этом вызове еще не появляются, и вы можете проверить это.
    Обратите внимание, что вызов не имеет своего собственного окружения, что означает, что вызов может давать разные результаты, если оценивается, например, из функции.
  • Выражения похожи на вызовы, но применяются более широко, то есть не всегда являются функцией, которая должна быть выполнена. Выражение может быть как именем переменной, так и простым значением, например "почему нет?". Кроме того, выражения могут состоять из нескольких единиц, как если бы вы использовали {

Различные функции могут конвертировать между этими классами, но иногда функции (такие как paste !) Также конвертируют неожиданно:

  • noquote не очень полезен, как уже указывало Moody_Mudskipper: он только меняет печать. Но объект в основном остается персонажем
  • substitute не только подставляет переменные, но и преобразует свой первый аргумент в (чаще всего) вызов. Здесь print кусает вас, потому что при печати звонка не предусмотрены специальные классы его участников. Попробуйте: sub[[3]] из вопроса дает
    [1] паста (курсив (да), "почему бы и нет?")
    без обратной косой черты! Только при распечатке полного вызова noquote-часть теряется.
  • parse используется для преобразования символа в выражение. Пока ничего не оценивается, но введена некоторая структура, чтобы вы могли манипулировать выражением.
  • paste часто ведет себя раздражающе (хотя и задокументировано), так как может вставлять только символы вместе -strings. Следовательно, если вы кормите его чем-либо, кроме символа, он сначала вызывает as.character. Поэтому, если вы позвоните ему, вы просто получите текстовую строку снова. Таким образом, в вашем вопросе, даже если вы используете синтаксический анализ, как только вы начнете вставлять что-то вместе, вы снова получите кавычки.

Наконец, ваша проблема сложнее, потому что она использует внутреннюю логику plotmath.
Это означает, что, как только вы попытаетесь оценить текст, вы, вероятно, получите сообщение об ошибке "не удалось найти курсив функции" (или более запутанную ошибку, если в другом месте определен italic функции). Предоставляя его в plotmath, он работает, потому что вызов оценивается только с помощью plotmath, что даст ему хорошую среду, в которой курсив работает, как и ожидалось.

Все это означает, что вам нужно рассматривать все это как выражение или вызов. До тех пор, пока оценка не может быть выполнена (если только вы обрабатываете выражение, а не plotmath), все это должно оставаться выражением или вызовом. Работает бесплатная замена вызова, но вы также можете более точно подражать тому, что происходит в R, с помощью

call('paste', 'Hi', parse(text=text)[[1]])

Ответ 3

Может быть, это может помочь:

text<-'paste(italic(yes),"why not?")'
text
[1] "paste(italic(yes),\"why not?\")"

text2 <- "paste(\"Hi\","
text2
[1] "paste(\"Hi\","

noqoute_text<-noquote(text)
noqoute_text
[1] paste(italic(yes),"why not?")

noqoute_text2<-noquote(text2)
noqoute_text2
[1] paste("Hi",

noquote(paste0(noqoute_text2,noqoute_text,')'))
[1] paste("Hi",paste(italic(yes),"why not?"))