Почему замена заменить текст кавычки на строку в 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?"))