Не знаете, как в R работает назначение/передача данных с данными

У меня проблемы с обдумыванием следующего примера:

Если я работаю с простыми числами, например.

library(dplyr)
x=5
y <- x %>% +1
y 
x
x==y

Я понял, что имел в виду, то есть x не изменился

> y 
[1] 6
> x
[1] 5
> x==y
[1] FALSE

Теперь я делаю это с таблицами данных:

library(data.table)
DT = data.table(id=c("A","B","C"),Value=c(1,2,3))
DT2 <- DT %>% .[,DoubleValue:=2*Value]
DT
DT2
DT==DT2

Я получаю то, что считаю концептуально другим:

> DT
   id Value DoubleValue
1:  A     1           2
2:  B     2           4
3:  C     3           6
> DT2
   id Value DoubleValue
1:  A     1           2
2:  B     2           4
3:  C     3           6
> DT==DT2
       id Value DoubleValue
[1,] TRUE  TRUE        TRUE
[2,] TRUE  TRUE        TRUE
[3,] TRUE  TRUE        TRUE

То есть DT на самом деле изменился

Большинство примеров, которые я нашел, на самом деле не используют часть <- и в любом случае рады изменить свой объект.

Почему DT изменено, а x нет?

Я не думаю, что это имеет какое-то отношение к оператору трубы. Вы получите тот же результат с DT2 <- DT[,DoubleValue:=2*Value]

Allan Cameron 18.12.2020 16:53

@AllanCameron Хм, я склоняюсь ко всему, поэтому я не понимал, что это что-то еще более фундаментальное, чего я не понял.

Anthony Martin 18.12.2020 16:56

Поскольку вы используете data.table, все изменения в таблице вносятся по ссылкам. То есть, даже если вы назначаете эту операцию DT2, исходному DT все еще назначено DoubleValue. Теперь у вас есть DT и DT2, указывающие на одну и ту же таблицу в памяти, обе с этой новой переменной.

r2evans 18.12.2020 16:58

Метод оператора <- для data.table объектов создает ссылку, а не копию. Подробности смотрите ?data.table::copy. data.table не был разработан с учетом взаимодействия с трубой magrittr.

bcarlsen 18.12.2020 16:58

Смотрите также этот вопрос-ответ

Allan Cameron 18.12.2020 16:59

@bcarlsen, но с ним он работает довольно хорошо, имхо. Конечно, предположение, что %>% является односторонним обратным клапаном потока данных, неверно, но я (лично) никогда не предполагал, что %>% обеспечивает это; сохранение исходных данных было связано с назначением или отсутствием их в начале или конце функции, а также с любыми промежуточными функциями, которые могли иметь побочный эффект.

r2evans 18.12.2020 16:59

Хорошо, и чтобы иметь копию, правильный способ - использовать copy()... Никогда не поздно знать основы

Anthony Martin 18.12.2020 17:04

@AllanCameron Интересный ответ, спасибо

Anthony Martin 18.12.2020 17:04

Кстати, поскольку мой вопрос неверен, а ответ на реальный вопрос уже где-то в другом месте, я полагаю, лучше удалить мой вопрос?

Anthony Martin 18.12.2020 17:10

если вы считаете, что ваш вопрос вряд ли будет полезен будущим читателям, удалите его. Если вы считаете, что ответ, который объясняет ваше замешательство, будет полезен будущим читателям, вы можете опубликовать ответ на свой вопрос.

Ben Bolker 18.12.2020 17:16
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
10
100
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Это на самом деле полностью связано с функциями data.table, а вовсе не с пайпингом.

Как более подробно описано здесь

DT2 <- DT
DT2[,DoubleValue:=2*Value]

тоже меняется DT

Это связано с нативной функцией, поскольку предполагается, что data.table обрабатывает большие базы данных, по умолчанию он избегает печатных копий, поэтому все операции <- создают только ссылки на общую базу данных.

Однако он меняется при изменении структуры, например.

DT2 <- DT[1:4]

Чтобы избежать этого и фактически изменить его, один из способов — использовать функцию copy().

DT2 <- copy(DT)

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