R:xtable和日期

yCa*_*ran 19 r date

我有以下数据:

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
Run Code Online (Sandbox Code Playgroud)

运行

> library(xtable)
> xtable(evolution)
Run Code Online (Sandbox Code Playgroud)

工作良好.但是,如果我添加该行

evolution$date <- as.Date(evolution$date, "%Y-%m-%d");
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

然后跑步xtable

Math.Date中的xtable(evolution)错误(x + ifelse(x == 0,1,0)):没有为Date对象定义abs

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
Run Code Online (Sandbox Code Playgroud)

Sim*_*nek 23

这可以说是一个错误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, ...)
}
Run Code Online (Sandbox Code Playgroud)


jor*_*ran 11

看来xtable并不总能很好地与Date类的列一起使用.(它确实有动物园ts方法,但如果在数据框中有一列日期/时间,那些可能无济于事,因为对动物园的强制似乎会改变结果表中的列名.)一些注意事项:

  1. 错误实际上是由print.xtable(不xtable.data.frame)抛出的,默认情况下会调用该错误以显示xtable控制台中的结果.因此,您会发现如果将结果存储xtable在变量中,则不会出现错误,但是当您尝试使用print它时,会弹出相同的错误.

  2. 由于您明智地将日期存储为YYYY-MM-DD格式,因此将它们转换为Date对象实际上不需要使用有序选择,因为它们将作为字符正确排序.所以你实际上可以简单地将它们保留为角色.

  3. 如果日期/时间对象更复杂,您可以先进行子集化,然后将这些列转换为字符.或者xtable.data.frame在开头创建一个包装器并添加行,

    dates <- sapply(x,FUN = function(x){class(x) == "Date"})
    x[,dates] <- as.character(x[,dates])
    
    Run Code Online (Sandbox Code Playgroud)

    检查课程日期,或您正在处理的任何课程.

  4. 恕我直言,xtable.data.frame应该检查日期,也可能检查其他POSIX类,并将它们转换为字符串.这可能是一个简单的更改,可能值得联系包作者.

  5. 最后,分号作为行终止符不是必需的.:)来自另一种语言的习惯?


小智 5

作为 xtable 的维护者,我想说明我认为关于 xtable 中日期的真实位置。

这并不是真正的错误,而是缺少您可能认为是可取的功能。

问题是 xtable 只能处理三类不同的列:逻辑;特点; 和数字。如果您尝试提交列的类为日期的表,则它无法处理它。相关代码是一组xtable方法,其中最重要的是xtable.data.frame和xtable.matrix。

这些方法的代码的第一部分处理检查提交的列的类,以便可以适当地处理它们。

也可以添加代码以允许类 Date 的列,但我不愿意这样做。

首先,有一个简单的解决方法(至少对于直接的 R 代码,我不能说对于 Shiny 应用程序),即将任何日期列更改为字符列:

其次,要允许 Date 类的列,需要向 xtable 和 xtable 方法(目前有 31 个)以及 xtableFtable 和 xtableList 添加一个参数。由于 xtable 的大量反向依赖关系,这充满了问题。(尚未计算,但如果您查看 CRAN 上的 xtable,您会看到一堆依赖项、导入项和建议。)如果我进行此类更改,我将破坏一些包,可能会破坏很多包。向后兼容性是 xtable 的一个严重问题。

为什么需要额外的论证?因为使用 xtable 的最终结果,或者更确切地说是 print.xtable,是一串字符。如何处理提交给 xtable 的数据框、矩阵或其他结构的列首先取决于它们的分类方式(逻辑、字符或数字),然后由参数 align、digits 和 display 决定,这些参数都可以是向量以允许用于不同列的不同处理。因此,如果允许日期,则需要一个额外的参数来指定它们的格式,因为在某些时候它们需要转换为字符以生成最终的表输出。