Добавление новых столбцов в справочную таблицу data.table внутри функции, которая не всегда работает

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

Вот небольшой пример:

 library(data.table) # I'm using 1.9.4 test <- data.table(id = letters[1:2], val=1:2) foobar <- function(dt, col) { dt[, (col) := 1] invisible(dt) } test # id val #1: a 1 #2: b 2 saveRDS(test, "test.rds") test2 <- readRDS("test.rds") all.equal(test, test2) #[1] TRUE foobar(test, "new") test # id val new #1: a 1 1 #2: b 2 1 foobar(test2, "new") test2 # id val #1: a 1 #2: b 2 

Что случилось? Чем отличается test2 ? Я могу изменить существующие столбцы на месте:

 foobar(test, "val") test # id val new #1: a 1 1 #2: b 1 1 foobar(test2, "val") test2 # id val #1: a 1 #2: b 1 

Но добавление к test2 все еще не работает:

 foobar(test2, "someothercol") .Last.value # id val someothercol #1: a 1 1 #2: b 1 1 test2 # id val #1: a 1 #2: b 1 

Я не могу зафиксировать все случаи, когда я вижу это поведение, но сохранение и чтение из RDS – это первый случай, который я могу достоверно реплицировать. Написание и чтение из CSV не похоже на ту же проблему.

Является ли это проблемой указателя ala этой проблемы , например, сериализация data.table уничтожает перенапряженные указатели? Есть ли простой способ восстановить их? Как я могу проверить их внутри своей функции, чтобы я мог восстановить указатели или ошибку, если операция не будет работать?

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

Ответ на решение Аруна

Арун дал указание, что это действительно проблема с указателем, которая может быть диагностирована с truelength и исправлена ​​с помощью setDT или alloc.col . Я столкнулся с проблемой, инкапсулирующей его решение в функцию (продолжающуюся сверху кода):

 func <- function(dt) {if (!truelength(dt)) setDT(dt)} func2 <- function(dt) {if (!truelength(dt)) alloc.col(dt)} test2 <- readRDS("test.rds") truelength(test2) #[1] 0 truelength(func(test2)) #[1] 100 truelength(test2) #[1] 0 truelength(func2(test2)) #[1] 100 truelength(test2) #[1] 0 

Таким образом, похоже, что локальная копия внутри функции правильно изменена, но эталонная версия отсутствует. Почему нет?

Является ли это проблемой указателя ala этой проблемы, например, сериализация data.table уничтожает перенапряженные указатели?

Да, загрузка с диска устанавливает внешний указатель на NULL. Нам снова придется перераспределять средства.

Есть ли простой способ восстановить их?

Да. Вы можете проверить для truelength() таблицы data.table, и если это 0 , то используйте setDT() или alloc.col() на нем.

 truelength(test2) # [1] 0 if (!truelength(test2)) setDT(test2) truelength(test2) # [1] 100 foobar(test2, "new") test2[] # id val new # 1: a 1 1 # 2: b 2 1 

Это, вероятно, следует рассматривать как часто задаваемые вопросы (не помню, чтобы увидеть их там).
В разделе часто задаваемых вопросов в разделе «Предупреждающие сообщения».

  • Использование списков внутри столбцов data.table
  • Ссылаясь на столбцы data.table именами, сохраненными в переменных
  • dplyr мутировать вычисления rowSums или пользовательские функции
  • Force R прекратить рисовать метки сокращенной оси - например, 1e + 00 в ggplot2
  • Как вы конвертируете дату POSIX в день года в R?
  • Как использовать функцию strsplit с периодом
  • идентифицировать группы связанных эпизодов, которые соединяются вместе
  • Как рисовать штабелированные столбцы в ggplot2, которые показывают процентные ставки по группе?
  • Разделить код на несколько строк в сценарии R
  • скептически отслеживает, как очистить данные с этого сайта (используя R)
  • создавая «радарную диаграмму» (также называемую сюжетной звездой, участок паука) с использованием ggplot2 в R
  • Interesting Posts

    .net UrlEncode – проблема с нижним регистром

    Предотвратить показ веб-страницы «веб-страница недоступна»

    Как я могу сделать снимок экрана моего экрана входа в Windows 7?

    Можно ли встраивать видео в YouTube в электронную почту HTML?

    Получить DbContext из Entity в Entity Framework

    Компиляция libjpeg

    Excel: сопоставление двух столбцов и выход третьего … И … в каждом столбце есть несколько экземпляров

    Объединение (использование одного и того же) профиля пользователя для XP и 7

    Как установить объекты File и length в объекте FileList, где файлы также отражаются в объекте FormData?

    Строковые литералы и escape-символы в postgresql

    Вывод типа Java: ссылка неоднозначна в Java 8, но не Java 7

    простое java regex throwing wrongstateexception

    iPhone – dealloc – Релиз против нуля

    Collapse / concatenate / aggregate column для отдельной строки, разделенной запятой, в каждой группе

    Является ли хорошей идеей обернуть #include в блоке пространства имен?

    Давайте будем гением компьютера.