R data.frame colnames в зависимости от оператора присваивания [duplicate]

Вы можете использовать что-то вроде этого:

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')
567
задан nbro 8 March 2018 в 10:30
поделиться

7 ответов

Разница в операторах присваивания понятна, когда вы используете их для установки значения аргумента в вызове функции. Например:

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 .

527
ответ дан Richie Cotton 15 August 2018 в 23:34
поделиться
  • 1
    Это также упоминается в главе 8.2.26 The R Inferno Патрика Бернса (не я, а рекомендация в любом случае) – Uwe 14 June 2016 в 09:17
  • 2
    Однако median((x = 1:10)) имеет тот же эффект, что и median(x <- 1:10). – Francesco Napolitano 27 September 2016 в 13:27
  • 3
    я действительно не считаю их ярлыками, в любом случае вы нажимаете одинаковое количество клавиш – yosemite_k 8 June 2018 в 12:42
  • 4
    Я просто понял, что ваше объяснение того, как интерпретируется x <- x = 5, немного неверно: на самом деле R интерпретирует его как ​`<-<-`(x, y = 5, value = 5) (что само по себе более или менее эквивалентно tmp <- x; x <- `<-<-`(tmp, y = 5, value = 5)). Хлоп! – Konrad Rudolph 27 July 2018 в 11:25
  • 5

По словам Джона Чамберса, оператор = разрешен только на «верхнем уровне», что означает, что он не разрешен в структурах управления, таких как if, что делает следующую ошибку программирования незаконной.

> if(x = 0) 1 else x
Error: syntax error

Как он пишет: «Запрещение новой формы присваивания [=] в контрольных выражениях позволяет избежать ошибок программирования (например, вышеприведенного примера), которые более вероятны с равным оператором, чем с другими S-назначениями».

Вы можете это сделать, если он «изолирован от окружающей логической структуры, скобками или дополнительной парой круглых скобок», поэтому if ((x = 0)) 1 else x будет работать.

См. http: // разработчик .r-project.org / equalAssign.html

28
ответ дан Aaron 15 August 2018 в 23:34
поделиться
  • 1
    Это обычная ошибка, x==0 почти всегда подразумевается. – Aaron 15 September 2014 в 16:04
  • 2
    Ах, да, я забыл, что вы сказали «ошибка программирования». На самом деле это хорошая новость, что это вызывает ошибку. И хорошая причина предпочесть x=0 как присвоение над x<-0! – Steve Pitchers 16 September 2014 в 10:55
  • 3
    Да, хорошо, что это вызывает ошибку, хотя я рисую другой урок о том, что предпочесть; Я предпочитаю использовать = как можно меньше, потому что = и == выглядят настолько похожими. – Aaron 16 September 2014 в 17:09
  • 4
    То, как этот пример представлен, настолько странно для меня. if(x = 0) 1 else x вызывает ошибку, помогая мне найти и исправить ошибку. if(x <- 1) 1 else x не вызывает ошибку и очень запутан. – Gregor 24 February 2017 в 22:32
  • 5
    Я имею в виду, что полезная проверка ошибок действительно могла бы вызвать там ошибку и сказать «у вас есть бесполезный код, который всегда будет возвращать значение 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 символ = имеет два разных значения, которые обычно объединяются:

  1. Первое значение является оператором присваивания . Это все, о чем мы говорили до сих пор.
  2. Второе значение - это не оператор, а токен синтаксиса , который сигнализирует с именем аргумент, передающий в вызове функции. В отличие от оператора = он не выполняет никаких действий во время выполнения, он просто меняет способ анализа выражения.

Давайте посмотрим.

В любом фрагменте кода общая форма ...

‹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, на самом деле объясняет это правильно:

[= присваивание] разрешено только в двух местах в грамматике: на верхнем уровне (как полная программа или пользовательское выражение); и когда они изолированы от окружающей логической структуры, скобками или дополнительной парой круглых скобок.


Исповедь: я солгал раньше. Там есть еще одно различие между операторами = и <-: они вызывают различные функции. По умолчанию эти функции выполняют одно и то же, но вы можете переопределить любой из них отдельно, чтобы изменить поведение. Напротив, <- и -> (назначение слева направо), хотя и синтаксически различны, всегда вызывают функцию же . Переопределение одного также переопределяет другое. Знание этого редко бывает практичным , но оно может быть использовано для некоторых забавных махинаций .

12
ответ дан Kobi 15 August 2018 в 23:34
поделиться

Операторы <- и = присваиваются в среду, в которой они вычисляются. Оператор <- можно использовать где угодно, , тогда как оператор = разрешен только на верхнем уровне (например, в полном выражении, введенном в командной строке) или в качестве одного из подвыражений в скопированный список выражений.

20
ответ дан nbro 15 August 2018 в 23:34
поделиться
  • 1
    Я думаю, что «верхний уровень» на уровне выписки, а не на уровне выражения. Таким образом, x <- 42 сам по себе является заявлением; в if (x <- 42) {} оно будет выражением и недействительным. Чтобы быть ясным, это не имеет никакого отношения к тому, находитесь ли вы в глобальной среде или нет. – Steve Pitchers 16 September 2014 в 10:58
  • 2
    Это: «оператор = разрешен только на верхнем уровне» является широко распространенным недоразумением и совершенно неправильным. – Konrad Rudolph 2 March 2017 в 15:20
  • 3
    Это неверно - например, это работает, даже если назначение не является полным выражением: 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

4
ответ дан Scarabee 15 August 2018 в 23:34
поделиться
  • 1
    можете ли вы дать более подробное объяснение, почему это происходит / что здесь происходит? (подсказка: data.frame пытается использовать имя предоставленной переменной в качестве имени элемента в кадре данных) – Ben Bolker 10 December 2016 в 23:16
  • 2
    Просто подумал, может ли это быть ошибкой? И если да, то как и где я могу сообщить об этом? – Denis Rasulev 15 July 2017 в 06:27
  • 3
    это не ошибка. Я попытался намекнуть на ответ в моем комментарии выше. При установке имени элемента R будет использовать эквивалент 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 для правил приоритета (привязки) и группировки.

27
ответ дан Steve Pitchers 15 August 2018 в 23:34
поделиться

Руководство по стилю R в Google упрощает проблему, запрещая присвоение «=». Неплохой выбор.

https://google.github.io/styleguide/Rguide.xml

В руководстве R содержатся подробные сведения обо всех 5 операторов присваивания.

http://stat.ethz.ch/R-manual/R-patched/library/base/html/assignOps.html

87
ответ дан xxfelixxx 15 August 2018 в 23:34
поделиться
  • 1
    Недостаток случайного присвоения x<-y, когда x < -y имел в виду, так сильно меня огорчает, что я лично предпочитаю =. Наличие вашего кода зависит от присутствующего пробела, кажется мне не очень хорошим. Можно ли предлагать интервал в качестве совета по стилю, но для того, чтобы ваш код работал по-разному, есть ли место или нет? Что делать, если вы переформатируете свой код или используете поиск и замену, пробелы могут иногда исчезать, а код идет не так. Это не проблема с =. IIUC, запрещающий = приравнивается к требованию «<- »; т. е. 3 символа, включая пробел, а не только «<-». – Matt Dowle 8 June 2012 в 16:16
  • 2
    Обратите внимание, что любое не-0 считается TRUE на R. Итак, если вы намерены проверить, что x меньше -y, вы можете написать if (x<-y), который не будет предупреждать или не будет ошибкой, и, похоже, работает нормально. Это будет только FALSE, когда y=0. – Matt Dowle 8 June 2012 в 16:21
  • 3
    Если вы запрещаете = и используете <- , то трудно утверждать, что дополнительный шаг grep "[^<]<-[^ ]" *.R не требуется. = не нуждается в таком grep. – Matt Dowle 8 June 2012 в 16:28
  • 4
    Зачем ваши глаза и палец повреждают <-, если вы можете использовать =? В 99,99% раз = штраф. Иногда вам нужно <<-, хотя это другая история. – Fernando 9 October 2013 в 02:22
  • 5
    Фокус на & lt; - является, пожалуй, одной из самых слабых причин отсутствия + = и - =. – Chris 11 November 2015 в 06:07
Другие вопросы по тегам:

Похожие вопросы: