R: xtable и даты
У меня есть следующие данные:
transaction <- c(1,2,3);
date <- c("2010-01-31","2010-02-28","2010-03-31");
type <- c("debit", "debit", "credit");
amount <- c(-500, -1000.97, 12500.81);
oldbalance <- c(5000, 4500, 17000.81)
evolution <- data.frame(transaction, date, type, amount, oldbalance, row.names=transaction, stringsAsFactors=FALSE);
evolution <- transform(evolution, newbalance = oldbalance + amount);
evolution
Запуск
> library(xtable)
> xtable(evolution)
работает отлично. Но если я добавлю строку
evolution$date <- as.Date(evolution$date, "%Y-%m-%d");
чтобы дать
transaction <- c(1,2,3);
date <- c("2010-01-31","2010-02-28","2010-03-31");
type <- c("debit", "debit", "credit");
amount <- c(-500, -1000.97, 12500.81);
oldbalance <- c(5000, 4500, 17000.81)
evolution <- data.frame(transaction, date, type, amount, oldbalance, row.names=transaction, stringsAsFactors=FALSE);
evolution$date <- as.Date(evolution$date, "%Y-%m-%d");
evolution <- transform(evolution, newbalance = oldbalance + amount);
evolution
тогда запуск xtable
дает
xtable (эволюция) Ошибка в Math.Date(x + ifelse (x == 0, 1, 0)): abs не определен для объектов Date
Но в этом случае полезно использовать xtable
, чтобы сделать некоторую фильтрацию дат
evolution$date <- as.Date(evolution$date, "%Y-%m-%d")
startdate <-as.Date("2010-02-01");
enddate <-as.Date("2010-03-30");
newdate <-evolution[which (evolution$date >= startdate & evolution$date <= enddate),]
newdate
> newdate
transaction date type amount oldbalance newbalance
2 2 2010-02-28 debit -1000.97 4500 3499.03
> xtable(newdate)
Error in Math.Date(x + ifelse(x == 0, 1, 0)) :
abs not defined for Date objects
Ответы
Ответ 1
Это, возможно, ошибка в xtable
- вы можете сообщить об этом сопровождающему.
Временная работа - вызов as.character()
для классов, которые xtable
неверно интерпретируют (кроме "Date", я могу думать о "POSIXt", но могут быть и другие), например:
xtable <- function(x, ...) {
for (i in which(sapply(x, function(y) !all(is.na(match(c("POSIXt","Date"),class(y))))))) x[[i]] <- as.character(x[[i]])
xtable::xtable(x, ...)
}
Ответ 2
Похоже, что xtable не всегда хорошо сочетается с столбцами класса Date. (У него есть методы zoo и ts, но это может не помочь, если у вас есть один столбец дат/времени в фрейме данных, как принуждение к зоопарку, похоже, изменяет имена столбцов в результирующей таблице.) Несколько примечаний:
-
Ошибка фактически вызывается print.xtable
, (not xtable.data.frame
), которая вызывается по умолчанию, чтобы отображать результаты xtable
в консоли. Таким образом, вы обнаружите, что если вы сохранили результаты xtable
в переменной, вы не получите никакой ошибки, но затем, когда вы попытаетесь выполнить print
, появится та же ошибка.
-
Поскольку вы мудро сохранили свои даты в формате YYYY-MM-DD, преобразование их в объекты Date фактически не требуется для использования упорядоченных выборов, поскольку они будут сортироваться должным образом в качестве символов. Таким образом, вы могли бы просто уйти, просто сохраняя их как символы.
-
В случаях с более сложными объектами даты и времени вы можете выполнить подмножество сначала, а затем преобразовать эти столбцы в символы. Или создайте обертку для xtable.data.frame
и добавьте строки в начале,
dates <- sapply(x,FUN = function(x){class(x) == "Date"})
x[,dates] <- as.character(x[,dates])
проверка класса Date или любого другого класса, с которым вы имеете дело.
-
IMHO, xtable.data.frame
должен, вероятно, проверять даты и, возможно, другие классы POSIX и преобразовывать их в строки. Это может быть простое изменение, и, возможно, стоит связаться с автором пакета.
-
Наконец, точки с запятой в качестве ограничителей строк не нужны.:) Привычка с другого языка?
Ответ 3
Как сопровождающий xtable, я хотел бы заявить о том, что я считаю истинной позицией в отношении дат в xtable.
Это на самом деле не ошибка, но отсутствие функции, которая может показаться вам желательной.
Проблема в том, что xtable может работать только с тремя разными классами столбцов: логический; персонаж; и числовой. Если вы попытаетесь отправить таблицу с классом столбца Date, он не сможет справиться с этим. Соответствующий код представляет собой набор методов xtable, наиболее важными из которых являются xtable.data.frame и xtable.matrix.
Первая часть кода для этих методов посвящена проверке класса представляемых столбцов, чтобы их можно было обработать соответствующим образом.
Можно было бы добавить код, чтобы разрешить столбцы класса Date, но я не хочу этого делать.
Во-первых, существует легкий обходной путь (по крайней мере, для прямого кода R, я не могу сказать, для приложений Shiny), который заключается в замене любого столбца Date на символьный столбец:
Во-вторых, чтобы разрешить столбцы класса Date, потребуется добавить аргумент к методам xtable и xtable (которых в настоящее время их 31), а также к xtableFtable и xtableList. Это чревато проблемами из-за большого количества обратных зависимостей для xtable. (Не в счет, но если вы посмотрите на xtable в CRAN, вы увидите стек зависимостей, импорт и предложения.) Я собираюсь разбить некоторые пакеты, может быть, много пакетов, если я сделаю такое изменение. Обратная совместимость - серьезная проблема с xtable.
Зачем нужен дополнительный аргумент? Потому что конечным результатом использования xtable, или более того, до точки print.xtable, является строка символов. То, как обрабатываются столбцы фрейма данных, матрицы или другой структуры, представленной в xtable, определяется сначала тем, как они классифицируются (логические, символьные или числовые), затем аргументами align, digits и display, которые могут быть векторами, которые позволяют для разной обработки разных колонн. Таким образом, если даты должны быть разрешены, вам понадобится дополнительный аргумент, чтобы указать, как они будут форматироваться, потому что в какой-то момент их необходимо преобразовать в символ для получения окончательного результата таблицы.