【问题标题】:read.csv in R reading dates differentlyR中的read.csv读取日期不同
【发布时间】:2015-07-07 20:17:33
【问题描述】:

我有两个非常相似的 csv 文件。从同一来源以相同格式下载的 2 只不同股票的股票价格。但是,R 中的 read.csv 读取它们的方式不同。

> tab1=read.csv(path1)
> tab2=read.csv(path2)

> head(tab1)
        Date   Open   High    Low  Close  Volume Adj.Close
1 2014-12-01 158.35 162.92 157.12 157.12 2719100  156.1488
2 2014-11-03 153.14 160.86 152.98 160.09 2243400  159.1004
3 2014-10-01 141.16 154.44 130.60 153.77 3825900  152.0036
4 2014-09-02 143.30 147.87 140.66 141.68 2592900  140.0525
5 2014-08-01 140.15 145.39 138.43 144.00 2027100  142.3459
6 2014-07-01 143.41 146.43 140.60 140.89 2131100  138.4461

> head(tab2)
       Date  Open  High   Low Close  Volume Adj.Close
1 12/1/2014 73.39 75.20 71.75 72.29 1561400  71.92211
2 11/3/2014 69.28 74.92 67.88 73.74 1421600  72.97650
3 10/1/2014 66.18 74.95 63.42 69.21 1775400  68.49341
4  9/2/2014 68.34 68.57 65.49 66.32 1249200  65.63333
5  8/1/2014 67.45 68.99 65.88 68.26 1655400  67.20743
6  7/1/2014 64.07 69.50 63.09 67.46 1733600  66.41976

如果我尝试在 read.csv 中使用 colClasses,则第二个表的日期读取不正确。

> tab1=read.csv(path1,colClasses=c("Date",rep("numeric",6)))
> tab2=read.csv(path2,colClasses=c("Date",rep("numeric",6)))

> head(tab1)
        Date   Open   High    Low  Close  Volume Adj.Close
1 2014-12-01 158.35 162.92 157.12 157.12 2719100  156.1488
2 2014-11-03 153.14 160.86 152.98 160.09 2243400  159.1004
3 2014-10-01 141.16 154.44 130.60 153.77 3825900  152.0036
4 2014-09-02 143.30 147.87 140.66 141.68 2592900  140.0525
5 2014-08-01 140.15 145.39 138.43 144.00 2027100  142.3459
6 2014-07-01 143.41 146.43 140.60 140.89 2131100  138.4461

> head(tab2)
        Date  Open  High   Low Close  Volume Adj.Close
1 0012-01-20 73.39 75.20 71.75 72.29 1561400  71.92211
2 0011-03-20 69.28 74.92 67.88 73.74 1421600  72.97650
3 0010-01-20 66.18 74.95 63.42 69.21 1775400  68.49341
4 0009-02-20 68.34 68.57 65.49 66.32 1249200  65.63333
5 0008-01-20 67.45 68.99 65.88 68.26 1655400  67.20743
6 0007-01-20 64.07 69.50 63.09 67.46 1733600  66.41976

不确定如何在不附加 .csv 文件的情况下重现此问题。我附上了这两个文件的快照。任何帮助将不胜感激。

谢谢

【问题讨论】:

  • 提供从文本编辑器复制的 .csv 文件的前几行如何?
  • 两个 csv 文件中的日期格式似乎不同。以字符形式读取日期列,然后在加载文件后转换为日期格式。例如tab2$Date = as.Date(tab2$Date, format="%m/%d/%Y").
  • 两个 csv 文件中的日期似乎格式相同。不知道如何测试这个,但在 excel 中,我尝试从每个表中的一个单元格输入 +1,日期为 2014 年 12 月 1 日,两者都显示 2014 年 12 月 2 日。我还在帖子中附上了两个 csv 的快照。

标签: r date csv read.csv


【解决方案1】:

这可以通过将日期作为字符向量读取,然后在 transform() 中调用 strptime() 来解决:

transform(read.csv(path2,colClasses=c('character',rep('numeric',6))),Date=as.Date(strptime(Date,'%m/%d/%Y')));
##         Date  Open  High   Low Close  Volume Adj.Close
## 1 2014-12-01 73.39 75.20 71.75 72.29 1561400  71.92211
## 2 2014-11-03 69.28 74.92 67.88 73.74 1421600  72.97650
## 3 2014-10-01 66.18 74.95 63.42 69.21 1775400  68.49341
## 4 2014-09-02 68.34 68.57 65.49 66.32 1249200  65.63333
## 5 2014-08-01 67.45 68.99 65.88 68.26 1655400  67.20743
## 6 2014-07-01 64.07 69.50 63.09 67.46 1733600  66.41976

编辑:您可以尝试使用自己的假设动态“检测”日期格式,但这只会与您的假设一样可靠:

readStockData <- function(path) {
    tab <- read.csv(path,colClasses=c('character',rep('numeric',6)));
    tab$Date <- as.Date(tab$Date,if (grepl('^\\d+/\\d+/\\d+$',tab$Date[1])) '%m/%d/%Y' else '%Y-%m-%d');
    tab;
};
readStockData(path1);
##         Date   Open   High    Low  Close  Volume Adj.Close
## 1 2014-12-01 158.35 162.92 157.12 157.12 2719100  156.1488
## 2 2014-11-03 153.14 160.86 152.98 160.09 2243400  159.1004
## 3 2014-10-01 141.16 154.44 130.60 153.77 3825900  152.0036
## 4 2014-09-02 143.30 147.87 140.66 141.68 2592900  140.0525
## 5 2014-08-01 140.15 145.39 138.43 144.00 2027100  142.3459
## 6 2014-07-01 143.41 146.43 140.60 140.89 2131100  138.4461
readStockData(path2);
##         Date  Open  High   Low Close  Volume Adj.Close
## 1 2014-12-01 73.39 75.20 71.75 72.29 1561400  71.92211
## 2 2014-11-03 69.28 74.92 67.88 73.74 1421600  72.97650
## 3 2014-10-01 66.18 74.95 63.42 69.21 1775400  68.49341
## 4 2014-09-02 68.34 68.57 65.49 66.32 1249200  65.63333
## 5 2014-08-01 67.45 68.99 65.88 68.26 1655400  67.20743
## 6 2014-07-01 64.07 69.50 63.09 67.46 1733600  66.41976

在上面我假设文件中至少有一条记录,并且所有记录都使用相同的日期格式,因此第一个日期值 (tab$Date[1]) 可用于检测。

【讨论】:

  • 这适用于第二个表,但不适用于第一个表。不幸的是,我有很多这样的表格要阅读,但不确定如何自动阅读。 head(transform(read.csv(path1,colClasses=c('character',rep('numeric',6))),Date=as.Date(strptime(Date,'%m/%d/%Y')))) ## Date Open High Low Close Volume Adj.Close ##1 158.35 162.92 157.12 157.12 2719100 156.1488 ##2 153.14 160.86 152.98 160.09 2243400 159.1004
  • 是的,编辑后的版本有效……非常感谢……知道为什么会出现这个奇怪的问题吗? R 或 csv 应该归咎于哪一个?
  • 由于第二个 CSV 文件中的日期格式不明确(可能是 %d/%m/%Y 或 %m/%d/%Y),因此 R 无法知道如何将其转换为日期,因此,至少在在这种特殊情况下,不能责怪 R。另一方面,有人可能会争辩说,R 的设计者本可以投入更多精力进行开箱即用的动态日期格式检测,因为我相信 as.Date() 只能处理 %Y-%m-%d,但可能具有一定的灵活性在分隔符上。但我不会责怪 R;将数据导入任何上下文通常需要输入格式的严格性和一致性。
  • 刚刚意识到同样重要的是要指出 Excel 对日期格式进行了一些相当激进的动态检测,然后使用相同的格式显示所有转换后的日期,因此即使基础 CSV 文件清楚地具有不同的日期格式,Excel 将掩盖它。您可以使用较低级别的文本编辑器或数据转储实用程序查看原始 CSV 数据来证明这一点。因此,如果我在上面的评论中不清楚这一点,那么 CSV 数据应该归咎于不一致。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多