Почему замена заменить текст кавычки на строку в R? - PullRequest
0 голосов
/ 26 августа 2018

Я хотел ответить на вопрос относительно 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?\")")

Ответы [ 2 ]

0 голосов
/ 10 декабря 2018

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

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

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

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

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

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

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

call('paste', 'Hi', parse(text=text)[[1]])
0 голосов
/ 04 декабря 2018

Вы используете неправильную функцию, используйте 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), но это совершенно другой зверь.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...