Как читается строка z <- "names<-"(z, "[<-"(names(z), 3, "c2")) в документации по именам?

Ссылаясь на этот пример:

z <- list(a = 1, b = "c", c = 1:3)  
names(z)  
# change just the name of the third element.  
names(z)[3] <- "c2"  
z  

Документация по именам говорит: «см. примеры. Это работает, потому что выражение там оценивается как z <- "names<-"(z, "[<-"(names(z), 3, "c2")) ."

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

names<- — это другая функция, которая выполняет задание
akrun 20.12.2020 23:13

@akrun Я многое понял, но "names<-" было слишком далеко для меня.

J. Mini 20.12.2020 23:16

Если набрать в консоли. вы получите ``names<-` function (x, value) .Primitive("names<-")# name# function (x) .Primitive("names")`

akrun 20.12.2020 23:17

Есть некоторые функции, которые имеют аналогичные аналоги присваивания, например. substring

akrun 20.12.2020 23:18

Просто помните, что часто, когда у вас есть funcname(leftside) <- rightside, это на самом деле звонок `funcname<-`(leftside, rightside)

thelatemail 20.12.2020 23:21

Я использовал обратные кавычки вместо двойных кавычек, поскольку двойные кавычки могут быть оценены как строка, а обратные кавычки оцениваются как есть.

akrun 21.12.2020 00:10

@thelatemail Я нашел иначе stackoverflow.com/q/65395373/10319707

J. Mini 21.12.2020 16:22
Почему в Python есть оператор &quot;pass&quot;?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
1
7
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Эта часть документации действительно написана плохо, я не виню вас за то, что вы запутались.

Вот краткий ответ, скажем, у вас есть вектор z = c(a = 1, b = 2, c = 3), тогда следующие эквивалентны:

names(z)[3] <- "c2"

и

z <- "names<-"(z, "[<-"(names(z), 3, "c2"))

Это все, что говорится в документации.

Вот более длинный ответ: в R вы, вероятно, знакомы с основным синтаксисом функции, поэтому, допустим, у вас есть foo = function(x,y) x + y, тогда вы, вероятно, привыкли вызывать foo(1, 2). Возможно, вы также видели «инфиксные» операторы, такие как +, так что вы, вероятно, знакомы с 1 + 2. Однако внутри это на самом деле читается как "+"(1,2) (попробуйте, это сработает). То же самое наблюдается с функциями присваивания и извлечения, например x[1] (для некоторого вектора x) или как в этом примере names(z)[3] <- , где <- — оператор присваивания.

Чтобы сделать этот пример еще более сложным, на самом деле используются два отдельных инфиксных оператора! Есть names<- и есть [<-, первый используется для установки имени вектора, а второй используется для установки значения в векторе после первого извлечения вектора (я знаю, что здесь происходит многое).

Итак, разберем, что эта строка говорит в более знакомом коде R:

z <- "names<-"(z, "[<-"(names(z), 3, "c2"))
  1. z: исходный вектор
  2. y = names(z): Вектор символов - имена z.
  3. y[3]<-"c2": извлеките третий элемент из y и присвойте ему значение «c2». Теперь мы в "[<-"(names(z), 3, "c2").
  4. names(z)<-y: Установите имена z как y. Теперь мы в "names<-"(z, "[<-"(names(z), 3, "c2")).

Просто чтобы еще больше запутать ситуацию, "names<-" не сохраняет новый именованный вектор, а просто устанавливает новые имена. Вот почему z <- "names<-"... требуется в конце, чтобы перезаписать исходную переменную с новым именем.

И показываю это с помощью R-кода:

> z = c(a = 1, b = 2, c = 3)
> print(z)
a b c 
1 2 3 
> names = names(z)
> names[3] = "c2"
> names(z) = names
> print(z)
 a  b c2 
 1  2  3 

Если "[<-" — это присваивание и извлечение, то почему "[<-"(names(z), 3, "c2") не означает «взять третий элемент имен (z) и присвоить ему «c2»?»

J. Mini 20.12.2020 23:42

Используя переменные в качестве примера: x[y] <- z эквивалентно "[<-"(x,y,z). Первый аргумент — это вектор, который нужно присвоить, второй — индекс элемента, который нужно изменить, третий — значение замены. Итак, здесь мы говорим: из названий z замените третье значение на «c2». Протестируйте это с помощью: '[<-'(letters, 1, "d")

RaphaelS 20.12.2020 23:56

Я думаю, вы пропустили шаг 5: последний z <- бит. Вероятно, также стоит отметить, что "[<-"(names(z), 3, "c2") возвращает все имена z.

J. Mini 21.12.2020 00:06

Я улучшил пример (надеюсь)

RaphaelS 21.12.2020 00:13

Итак, что нужно знать о names(z)<-, так это то, что на самом деле он не просто берет вектор и меняет его имена, он делает следующее: i) получает имена; ii) изменить имена; iii) перезаписать исходную переменную новыми именами. Это очень тонкий момент в R-кодировании, и единственный способ понять его — протестировать, просто запустите следующее, и вы поймете, что я имею в виду: z = c(a = 1, b = 2, c = 3); "names<-"(z, "[<-"(names(z), 3, "c2")). Вы должны увидеть, что "names<-" на самом деле не сохраняет результат, поэтому вам нужно перезаписать z

RaphaelS 21.12.2020 10:00

Я согласен, я отредактировал ответ после того, как написал комментарий. Рад, что на ваш вопрос теперь дан ответ. А также спасибо за вызов объяснить это.

RaphaelS 21.12.2020 14:25

Меня все еще не совсем устраивает это. Предположение о том, что "names<-"(x,y) не идентично names(x)<-y, похоже, противоречит тому, как должны работать операторы инфликса.

J. Mini 21.12.2020 15:48

Странно, наверное, я не думал об этом раньше. Это справедливо для всех операторов присваивания в R, например: x = 1:2; "[<-"(x,1,3). Я предполагаю, что это связано с семантикой копирования при изменении?

RaphaelS 21.12.2020 16:04

Я задам новый вопрос об этом.

J. Mini 21.12.2020 16:11

Другие вопросы по теме