Вы можете использовать что-то вроде этого:
import re
s = #that big string
# the parenthesis create a group with what was matched
# and '\w' matches only alphanumeric charactes
p = re.compile("name +(\w+) +is valid", re.flags)
# use search(), so the match doesn't have to happen
# at the beginning of "big string"
m = p.search(s)
# search() returns a Match object with information about what was matched
if m:
name = m.group(1)
else:
raise Exception('name not found')
Разница в операторах присваивания понятна, когда вы используете их для установки значения аргумента в вызове функции. Например:
median(x = 1:10)
x
## Error: object 'x' not found
В этом случае x
объявляется в пределах области действия функции, поэтому он не существует в рабочей области пользователя.
median(x <- 1:10)
x
## [1] 1 2 3 4 5 6 7 8 9 10
В этот случай, x
объявлен в рабочей области пользователя, поэтому вы можете использовать его после завершения вызова функции.
В сообществе R есть общий способ использования <-
для назначения (кроме сигнатур функций) для совместимости с (очень) старыми версиями S-Plus. Обратите внимание, что пробелы помогают прояснить ситуации, такие как
x<-3
# Does this mean assignment?
x <- 3
# Or less than?
x < -3
. Большинство R IDE имеют быстрые клавиши, чтобы сделать <-
проще для ввода. Ctrl + = в архитекторе, Alt + - в RStudio (Option + - под macOS), Shift + - (подчеркивание) в emacs + ESS.
Если вы предпочитаете писать =
на <-
, но вы хотите использовать более общий символ назначения для общедоступного кода (например, на CRAN), то вы можете использовать одну из функций tidy_*
в пакете formatR
для автоматической замены =
с <-
.
library(formatR)
tidy_source(text = "x=1:5", arrow = TRUE)
## x <- 1:5
Ответ на вопрос «Почему x <- y = 5
выдает ошибку, но не x <- y <- 5
?» «Это зависит от магии, содержащейся в парсере». Синтаксис R содержит много неоднозначных случаев , которые должны быть решены так или иначе. Парсер решает разрешить биты выражения в разных порядках в зависимости от того, использовались ли =
или <-
.
Чтобы понять, что происходит, вам нужно знать, что назначение тихо возвращает значение, которое был назначен. Вы можете увидеть это более четко, явно напечатав, например, print(x <- 2 + 3)
.
Во-вторых, это яснее, если мы используем префиксную нотацию для назначения. Итак,
x <- 5
`<-`(x, 5) #same thing
y = 5
`=`(y, 5) #also the same thing
Парсер интерпретирует x <- y <- 5
как
`<-`(x, `<-`(y, 5))
. Мы могли бы ожидать, что x <- y = 5
будет
`<-`(x, `=`(y, 5))
, но на самом деле он интерпретируется как
`=`(`<-`(x, y), 5)
Это связано с тем, что =
имеет более низкий приоритет, чем <-
, как показано на странице справки ?Syntax
.
По словам Джона Чамберса, оператор =
разрешен только на «верхнем уровне», что означает, что он не разрешен в структурах управления, таких как if
, что делает следующую ошибку программирования незаконной.
> if(x = 0) 1 else x
Error: syntax error
Как он пишет: «Запрещение новой формы присваивания [=] в контрольных выражениях позволяет избежать ошибок программирования (например, вышеприведенного примера), которые более вероятны с равным оператором, чем с другими S-назначениями».
Вы можете это сделать, если он «изолирован от окружающей логической структуры, скобками или дополнительной парой круглых скобок», поэтому if ((x = 0)) 1 else x
будет работать.
x=0
как присвоение над x<-0
!
– Steve Pitchers
16 September 2014 в 10:55
=
как можно меньше, потому что =
и ==
выглядят настолько похожими.
– Aaron
16 September 2014 в 17:09
if(x = 0) 1 else x
вызывает ошибку, помогая мне найти и исправить ошибку. if(x <- 1) 1 else x
не вызывает ошибку и очень запутан.
– Gregor
24 February 2017 в 22:32
else
, вы имели в виду написать его таким образом?», но это может быть мечтой ...
– TylerH
8 March 2017 в 18:13
Каковы различия между операторами присваивания
=
и<-
в R?Как показывает ваш пример,
=
и<-
имеют несколько иные приоритет оператора (который определяет порядок оценки, когда они смешиваются в одном выражении). Фактически,?Syntax
в R дает следующую таблицу приоритета оператора: от наивысшего до самого низкого:… ‘-> ->>’ rightwards assignment ‘<- <<-’ assignment (right to left) ‘=’ assignment (right to left) …
Но это единственная разница ?
Поскольку вы спрашивали о операторах присваивания : да, это единственная разница. Однако вам будет отказано в вере. Даже документация R в
?assignOps
утверждает, что существует больше различий:Оператор
<-
можно использовать в любом месте, тогда как оператор=
разрешено на верхнем уровне (например, в полном выражении, введенном в командной строке) или в качестве одного из подвыражений в скобках списка выражений.Давайте не будем слишком тонко очертить это: R-документация (тонко) неверна [ 1 ]. Это легко показать: нам просто нужно найти встречный пример оператора
=
, который не является (a) на верхнем уровне, и (b) подвыражение в скобках списка выражений (т.е.{…; …}
). - Без дальнейших церемоний:x # Error: object 'x' not found sum((x = 1), 2) # [1] 3 x # [1] 1
Очевидно, что мы выполнили назначение, используя
=
, вне контекстов (a) и (b). Итак, почему документация о ключевой языковой функции R была неправильной на протяжении десятилетий?Это связано с тем, что в синтаксисе R символ
=
имеет два разных значения, которые обычно объединяются:
- Первое значение является оператором присваивания . Это все, о чем мы говорили до сих пор.
- Второе значение - это не оператор, а токен синтаксиса , который сигнализирует с именем аргумент, передающий в вызове функции. В отличие от оператора
=
он не выполняет никаких действий во время выполнения, он просто меняет способ анализа выражения.Давайте посмотрим.
В любом фрагменте кода общая форма ...
‹function_name›(‹argname› = ‹value›, …) ‹function_name›(‹args›, ‹argname› = ‹value›, …)
...
=
- это токен, который определяет передачу именованных аргументов: это not оператор присваивания. Кроме того,=
полностью запрещен в некоторых синтаксических контекстах:if (‹var› = ‹value›) … while (‹var› = ‹value›) … for (‹var› = ‹value› in ‹value2›) … for (‹var1› in ‹var2› = ‹value›) …
Любой из них вызовет ошибку «неожиданный» = «в
».
В любом другом контексте
=
ссылается на вызов оператора присваивания. В частности, просто размещение круглых скобок вокруг подвыражения делает любой из вышеперечисленных (a) действительными и (b) присвоением . Например, следующее выполняет назначение:median((x = 1 : 10))
Но также:
if (! (nf = length(from))) return()
Теперь вы можете возразить, что такой код является жестоким (и вы можете быть правы). Но я взял этот код из функции
base::file.copy
(заменив<-
на=
) - это распространенный шаблон в большей части основной базы кода R.Исходное объяснение от John Chambers , на котором, вероятно, основана документация R, на самом деле объясняет это правильно:
[
=
присваивание] разрешено только в двух местах в грамматике: на верхнем уровне (как полная программа или пользовательское выражение); и когда они изолированы от окружающей логической структуры, скобками или дополнительной парой круглых скобок.
Исповедь: я солгал раньше. Там есть еще одно различие между операторами
=
и<-
: они вызывают различные функции. По умолчанию эти функции выполняют одно и то же, но вы можете переопределить любой из них отдельно, чтобы изменить поведение. Напротив,<-
и->
(назначение слева направо), хотя и синтаксически различны, всегда вызывают функцию же . Переопределение одного также переопределяет другое. Знание этого редко бывает практичным , но оно может быть использовано для некоторых забавных махинаций .
Операторы <-
и =
присваиваются в среду, в которой они вычисляются. Оператор <-
можно использовать где угодно, , тогда как оператор =
разрешен только на верхнем уровне (например, в полном выражении, введенном в командной строке) или в качестве одного из подвыражений в скопированный список выражений.
x <- 42
сам по себе является заявлением; в if (x <- 42) {}
оно будет выражением и недействительным. Чтобы быть ясным, это не имеет никакого отношения к тому, находитесь ли вы в глобальной среде или нет.
– Steve Pitchers
16 September 2014 в 10:58
1 + (x = 2)
– Pavel Minaev
5 March 2017 в 23:52
Это также может добавить к пониманию разницы между этими двумя операторами:
df <- data.frame(
a = rnorm(10),
b <- rnorm(10)
)
Для первого элемента R присвоены значения и собственное имя, тогда как имя второго элемента выглядит немного странным .
str(df)
# 'data.frame': 10 obs. of 2 variables:
# $ a : num 0.6393 1.125 -1.2514 0.0729 -1.3292 ...
# $ b....rnorm.10.: num 0.2485 0.0391 -1.6532 -0.3366 1.1951 ...
R версия 3.3.2 (2016-10-31); macOS Sierra 10.12.1
data.frame
пытается использовать имя предоставленной переменной в качестве имени элемента в кадре данных)
– Ben Bolker
10 December 2016 в 23:16
make.names("b <- rnorm(10)")
.
– Ben Bolker
16 July 2017 в 15:21
x = y = 5
эквивалентен x = (y = 5)
, поскольку работает оператор присваивания «группа» справа налево. Значение: присвойте 5 на y
, оставив номер 5; а затем назначьте это значение 5 в x
.
Это не то же самое, что (x = y) = 5
, что не работает! Значение: присвойте значение y
x
, оставив значение y
; а затем назначьте 5, umm ..., что именно?
Когда вы смешиваете разные типы операторов присваивания, <-
привязывается сильнее, чем =
. Таким образом, x = y <- 5
интерпретируется как x = (y <- 5)
, что имеет смысл.
К сожалению, x <- y = 5
интерпретируется как (x <- y) = 5
, что не работает!
См. ?Syntax
и ?assignOps
для правил приоритета (привязки) и группировки.
Руководство по стилю R в Google упрощает проблему, запрещая присвоение «=». Неплохой выбор.
https://google.github.io/styleguide/Rguide.xml
В руководстве R содержатся подробные сведения обо всех 5 операторов присваивания.
http://stat.ethz.ch/R-manual/R-patched/library/base/html/assignOps.html
x<-y
, когда x < -y
имел в виду, так сильно меня огорчает, что я лично предпочитаю =
. Наличие вашего кода зависит от присутствующего пробела, кажется мне не очень хорошим. Можно ли предлагать интервал в качестве совета по стилю, но для того, чтобы ваш код работал по-разному, есть ли место или нет? Что делать, если вы переформатируете свой код или используете поиск и замену, пробелы могут иногда исчезать, а код идет не так. Это не проблема с =
. IIUC, запрещающий =
приравнивается к требованию «<-
»; т. е. 3 символа, включая пробел, а не только «<-
».
– Matt Dowle
8 June 2012 в 16:16
TRUE
на R. Итак, если вы намерены проверить, что x
меньше -y
, вы можете написать if (x<-y)
, который не будет предупреждать или не будет ошибкой, и, похоже, работает нормально. Это будет только FALSE
, когда y=0
.
– Matt Dowle
8 June 2012 в 16:21
=
и используете <-
, то трудно утверждать, что дополнительный шаг grep "[^<]<-[^ ]" *.R
не требуется. =
не нуждается в таком grep
.
– Matt Dowle
8 June 2012 в 16:28
<-
, если вы можете использовать =
? В 99,99% раз =
штраф. Иногда вам нужно <<-
, хотя это другая история.
– Fernando
9 October 2013 в 02:22
median((x = 1:10))
имеет тот же эффект, что иmedian(x <- 1:10)
. – Francesco Napolitano 27 September 2016 в 13:27x <- x = 5
, немного неверно: на самом деле R интерпретирует его как`<-<-`(x, y = 5, value = 5)
(что само по себе более или менее эквивалентноtmp <- x; x <- `<-<-`(tmp, y = 5, value = 5)
). Хлоп! – Konrad Rudolph 27 July 2018 в 11:25