У меня проблемы с обдумыванием следующего примера:
Если я работаю с простыми числами, например.
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 нет?
@AllanCameron Хм, я склоняюсь ко всему, поэтому я не понимал, что это что-то еще более фундаментальное, чего я не понял.
Поскольку вы используете data.table, все изменения в таблице вносятся по ссылкам. То есть, даже если вы назначаете эту операцию DT2, исходному DT все еще назначено DoubleValue. Теперь у вас есть DT и DT2, указывающие на одну и ту же таблицу в памяти, обе с этой новой переменной.
Метод оператора <- для data.table объектов создает ссылку, а не копию. Подробности смотрите ?data.table::copy. data.table не был разработан с учетом взаимодействия с трубой magrittr.
Смотрите также этот вопрос-ответ
@bcarlsen, но с ним он работает довольно хорошо, имхо. Конечно, предположение, что %>% является односторонним обратным клапаном потока данных, неверно, но я (лично) никогда не предполагал, что %>% обеспечивает это; сохранение исходных данных было связано с назначением или отсутствием их в начале или конце функции, а также с любыми промежуточными функциями, которые могли иметь побочный эффект.
Хорошо, и чтобы иметь копию, правильный способ - использовать copy()... Никогда не поздно знать основы
@AllanCameron Интересный ответ, спасибо
Кстати, поскольку мой вопрос неверен, а ответ на реальный вопрос уже где-то в другом месте, я полагаю, лучше удалить мой вопрос?
Если вы считаете, что ваш вопрос вряд ли будет полезен будущим читателям, удалите его. Если вы считаете, что ответ, который объясняет ваше замешательство, будет полезен будущим читателям, вы можете опубликовать ответ на свой вопрос.
Это на самом деле полностью связано с функциями data.table, а вовсе не с пайпингом.
Как более подробно описано здесь
DT2 <- DT
DT2[,DoubleValue:=2*Value]
Тоже меняется DT
Это связано с нативной функцией, поскольку предполагается, что data.table обрабатывает большие базы данных, по умолчанию он избегает печатных копий, поэтому все операции <- создают только ссылки на общую базу данных.
Однако он меняется при изменении структуры, например.
DT2 <- DT[1:4]
Чтобы избежать этого и фактически изменить его, один из способов — использовать функцию copy().
DT2 <- copy(DT)
Я не думаю, что это имеет какое-то отношение к оператору трубы. Вы получите тот же результат с DT2 <- DT[,DoubleValue:=2*Value]