Что вы можете сделать с data.frame, что вы не можете с data.table?

Я только начал использовать R и наткнулся на data.table. Я нашел его блестящим.

Очень наивный вопрос: могу ли я игнорировать data.frame для использования data.table, чтобы избежать путаницы синтаксиса между двумя пакетами?

Ответ 1

Из FAQ.table FAQ

FAQ 1.8 Хорошо, я начинаю видеть, что такое data.table, но почему вы не улучшили data.frame в R? Почему это должен быть новый пакет?

Как подчеркивается в FAQ 1.1, j в [.data.table принципиально отличается от j в [.data.frame. Даже так просто, как DF[,1] сломает существующий код во многих пакетах и код пользователя. Это сделано специально, и мы хотим, чтобы это работало сложный синтаксис для работы. Есть и другие отличия (см. FAQ 2,17).

Кроме того, data.table наследуется от data.frame. Это data.frame тоже. data.table может быть передан любому пакету, который принимает только data.frame, и этот пакет может использовать [.data.frame синтаксис в data.table.

Мы также предложили улучшения для R, где это возможно. Один из они были приняты в качестве новой функции в R 2.12.0:

  unique() и match() теперь работают быстрее на символьных векторах, где все элементы находятся в глобальном кэше CHARSXP и не отмечены   кодирование (ASCII). Спасибо Мэтью Доул за предложение улучшения   к тому, как хеш-код генерируется в unique. c.

Второе предложение заключалось в использовании memcpy в duplicate.c, что значительно быстрее, чем цикл for в C. Это улучшит способ, которым R копирует данные внутренне (по некоторым показателям в 13 раз). Нить на р-девел здесь: http://tolstoy.newcastle.edu.au/R/e10/devel/10/04/0148.html.

Каковы меньшие синтаксические различия между data.frame и data.table

  • DT[3] относится к 3-й строке, но DF[3] относится к 3-му столбцу
  • DT[3, ] == DT[3], но DF[ , 3] == DF[3] (несколько запутанно в data.frame, тогда как data.table согласован)
  • По этой причине мы говорим, что запятая необязательна в DT, но не обязательна в DF
  • DT[[3]] == DF[, 3] == DF[[3]]
  • DT[i, ], где i - одно целое число, возвращает одну строку, как и DF[i, ], но в отличие от подмножества матрицы, состоящего из одной строки, которое возвращает вектор.
  • DT[ , j] где j - одно целое число, возвращает таблицу data.table с одним столбцом, в отличие от DF[, j], который возвращает вектор по умолчанию
  • DT[ , "colA"][[1]] == DF[ , "colA"].
  • DT[ , colA] == DF[ , "colA"] (в настоящее время в data.table v1.9.8, но собирается измениться, см. заметки о выпуске)
  • DT[ , list(colA)] == DF[ , "colA", drop = FALSE]
  • DT[NA] возвращает 1 строку NA, но DF[NA] возвращает всю копию DF, содержащую NA. Символ NA имеет тип logical в R и поэтому перерабатывается [.data.frame. Вероятно, намерение пользователя было DF[NA_integer_]. [.data.table автоматически переключается на это вероятное намерение для удобства.
  • DT[c(TRUE, NA, FALSE)] обрабатывает NA как FALSE, но DF[c(TRUE, NA, FALSE)] возвращает NA строк для каждого NA
  • DT[ColA == ColB] проще, чем DF[!is.na(ColA) & !is.na(ColB) & ColA == ColB, ]
  • data.frame(list(1:2, "k", 1:4)) создает 3 столбца, data.table создает один столбец list.
  • check.names по умолчанию TRUE в data.frame, но FALSE в data.table для удобства.
  • stringsAsFactors по умолчанию TRUE в data.frame, но FALSE в data.table для эффективности. Поскольку к R был добавлен глобальный строковый кеш, символьные элементы являются указателем на одну кешированную строку, и при преобразовании в factor выигрыша в производительности больше нет.
  • Атомные векторы в столбцах list свернуты при печати с использованием ", " в data.frame, но "," в data.table с запятой после 6-го элемента, чтобы избежать случайной печати больших вложенных объектов. В [.data.frame мы очень часто устанавливаем drop = FALSE. Когда мы забываем, ошибки могут возникать в крайних случаях, когда выбираются отдельные столбцы и внезапно возвращается вектор, а не один столбец data.frame. В [.data.table мы воспользовались возможностью, чтобы сделать его последовательным, и отбросили drop. Когда data.table передается в пакет data.table-unaware, этот пакет не связан ни с одним из этих различий; это просто работает.

Небольшая оговорка

Возможно, будут случаи, когда в некоторых пакетах используется код, который падает, когда передается data.frame, однако, учитывая, что data.table постоянно поддерживается, чтобы избежать таких проблем, любые проблемы, которые могут возникнуть, будут быстро исправлены.

Например,

  • base :: unname (DT) теперь снова работает, как того требует plyr :: melt(). Благодаря Кристофа Джеккеля за репортаж. Тест добавлен.
  • Для ITime был добавлен метод as.data.frame, так что ITime может быть передан ggplot2     без ошибок, № 1713. Спасибо Фаррелу Бучинскому за сообщение. Тесты добавлены.     Метки оси ITime по-прежнему отображаются в виде целых секунд с полуночи; мы не знаем, почему ggplot2     не вызывает метод ITime as.character. Конвертировать ITime в POSIXct для ggplot2, это один из подходов.