从带有时间戳的 csv 导入数据
Import data from csv with timestamps
我的 csv 文件如下所示:
A,A,B,B,C,C,…
Timestamp,Price,Timestamp,Price,Timestamp,Price,…
6/1/15,20,6/1/15,97,6/1/15,279,…
5/29/15,21,5/29/15,96,5/29/15,276,…
其中 A-C 是具有每日价格的股票。我想把它转换成这种形式,
A B C
6/01/2015 20 97 279
5/29/2015 21 96 276
m/d/Y price price price
首先我尝试使用 readSeries(file="name.csv", header=TRUE, sep=";", format="%d/%m/%Y")
但是我得到的日期和每只股票在单独列中的价格。看起来像这样
A A B B C C
[1,] 06/01/2015 20 06/01/2015 97 06/01/2015 279
[2,] 5/29/2015 21 5/29/2015 96 5/29/2015 276
我的第二次尝试是用 read.zoo(file="name.csv", sep=",", header=TRUE, index="Timestamp", format="%m/%d/%Y")
阅读它。这里我得到错误信息index has 6375 bad entries at data rows
,但是格式是正确的。
我的问题是这两个应用函数中的哪一个更适合我的问题,我怎样才能达到我想要的输出?
也许这就足够了?
stocks="A,A,B,B,C,C
6/1/15,20,6/1/15,97,6/1/15,279
5/29/15,21,5/29/15,96,5/29/15,276
"
df = read.csv(text=stocks)
s = seq (2, ncol(df), by = 2)
idx = c(1, s) # only want 1st column and stock price columns
df2 = df[,idx]
colnames(df2) = c("date", colnames(df)[s-1])
输出df2
date A B C
1 6/1/15 20 97 279
2 5/29/15 21 96 276
更新:
根据评论讨论,我用下面的代码替换了 colnames(df2)...
行,以便以正确的格式放置日期并将它们放在数据框的行名中。不幸的是,数据框的行名只能是字符向量,不能是日期格式。 (旁注:小心在数据框中使用行名:http://www.perfectlyrandom.org/2015/06/16/never-trust-the-row-names-of-a-dataframe-in-R/
)
rownames(df2) = strftime(as.Date(df2[,1], "%m/%d/%y"), format = "%m/%d/%Y")
df2[,1]=NULL
colnames(df2) = c(colnames(df)[s-1])
输出df2
A B C
06/01/2015 20 97 279
05/29/2015 21 96 276
1)这里我们使用read.zoo
。我们使用 textConnection(Lines)
和 text=Lines
来保持这种自包含,但实际上用 file = "name.csv"
替换了每个。
首先我们计算给出 n
的字段。然后我们读入数据并指定 header、comma-separated 字段和日期格式。 (请注意,给定问题顶部显示的数据,格式应将年份指定为 %y
而不是问题中显示的 %Y
。)输入的第二行以 T 开头所以指定 T 开始注释以有效地跳过该行。接下来我们指定 check.names=FALSE
以防止它混淆列名。最后,假设每行的日期相同,这样我们只需要每行的第一个日期。使用 colClasses
我们可以省略其他日期列,方法是指定它们属于 class NULL
.
library(zoo)
Lines <- "A,A,B,B,C,C
Timestamp,Price,Timestamp,Price,Timestamp,Price
6/1/15,20,6/1/15,97,6/1/15,279
5/29/15,21,5/29/15,96,5/29/15,276"
n <- count.fields(textConnection(Lines), sep = ",")[1]
colClasses <- c("character", "numeric", rep(c("NULL", "numeric"), n/2-1))
read.zoo(text = Lines, header = TRUE, sep = ",", format = "%m/%d/%y",
comment = "T", check.names = FALSE, colClasses = colClasses)
这给出:
A B C
2015-05-29 21 96 276
2015-06-01 20 97 279
如果可以硬编码字段的数量,我们可以通过省略 count.fields
语句并将 n/2-1
替换为 2
来略微减少代码。
1a) 如果 header 行中可以有 T,则使用此代替:
L <- readLines(textConnection(Lines))[-2]
read.zoo(text = L, header = TRUE, sep = ",", format = "%m/%d/%y",
check.names = FALSE, colClasses = colClasses)
2) 使用上面计算的 colClasses
的 base R 的替代方案是:
DF <- read.csv(text = Lines, comment = "T", check.names = FALSE, colClasses = colClasses)
DF[[1]] <- as.Date(DF[[1]], "%m/%d/%y")
names(DF)[1] <- "Date"
2a) 类似地,如果第一行可以包含 T 则使用此代替,其中 L
来自 (1a),colClasses
来自(1).
DF <- read.csv(text = L, check.names = FALSE, colClasses = colClasses)
DF[[1]] <- as.Date(DF[[1]], "%m/%d/%y")
names(DF)[1] <- "Date"
我的 csv 文件如下所示:
A,A,B,B,C,C,…
Timestamp,Price,Timestamp,Price,Timestamp,Price,…
6/1/15,20,6/1/15,97,6/1/15,279,…
5/29/15,21,5/29/15,96,5/29/15,276,…
其中 A-C 是具有每日价格的股票。我想把它转换成这种形式,
A B C
6/01/2015 20 97 279
5/29/2015 21 96 276
m/d/Y price price price
首先我尝试使用 readSeries(file="name.csv", header=TRUE, sep=";", format="%d/%m/%Y")
但是我得到的日期和每只股票在单独列中的价格。看起来像这样
A A B B C C
[1,] 06/01/2015 20 06/01/2015 97 06/01/2015 279
[2,] 5/29/2015 21 5/29/2015 96 5/29/2015 276
我的第二次尝试是用 read.zoo(file="name.csv", sep=",", header=TRUE, index="Timestamp", format="%m/%d/%Y")
阅读它。这里我得到错误信息index has 6375 bad entries at data rows
,但是格式是正确的。
我的问题是这两个应用函数中的哪一个更适合我的问题,我怎样才能达到我想要的输出?
也许这就足够了?
stocks="A,A,B,B,C,C
6/1/15,20,6/1/15,97,6/1/15,279
5/29/15,21,5/29/15,96,5/29/15,276
"
df = read.csv(text=stocks)
s = seq (2, ncol(df), by = 2)
idx = c(1, s) # only want 1st column and stock price columns
df2 = df[,idx]
colnames(df2) = c("date", colnames(df)[s-1])
输出df2
date A B C
1 6/1/15 20 97 279
2 5/29/15 21 96 276
更新:
根据评论讨论,我用下面的代码替换了 colnames(df2)...
行,以便以正确的格式放置日期并将它们放在数据框的行名中。不幸的是,数据框的行名只能是字符向量,不能是日期格式。 (旁注:小心在数据框中使用行名:http://www.perfectlyrandom.org/2015/06/16/never-trust-the-row-names-of-a-dataframe-in-R/
)
rownames(df2) = strftime(as.Date(df2[,1], "%m/%d/%y"), format = "%m/%d/%Y")
df2[,1]=NULL
colnames(df2) = c(colnames(df)[s-1])
输出df2
A B C
06/01/2015 20 97 279
05/29/2015 21 96 276
1)这里我们使用read.zoo
。我们使用 textConnection(Lines)
和 text=Lines
来保持这种自包含,但实际上用 file = "name.csv"
替换了每个。
首先我们计算给出 n
的字段。然后我们读入数据并指定 header、comma-separated 字段和日期格式。 (请注意,给定问题顶部显示的数据,格式应将年份指定为 %y
而不是问题中显示的 %Y
。)输入的第二行以 T 开头所以指定 T 开始注释以有效地跳过该行。接下来我们指定 check.names=FALSE
以防止它混淆列名。最后,假设每行的日期相同,这样我们只需要每行的第一个日期。使用 colClasses
我们可以省略其他日期列,方法是指定它们属于 class NULL
.
library(zoo)
Lines <- "A,A,B,B,C,C
Timestamp,Price,Timestamp,Price,Timestamp,Price
6/1/15,20,6/1/15,97,6/1/15,279
5/29/15,21,5/29/15,96,5/29/15,276"
n <- count.fields(textConnection(Lines), sep = ",")[1]
colClasses <- c("character", "numeric", rep(c("NULL", "numeric"), n/2-1))
read.zoo(text = Lines, header = TRUE, sep = ",", format = "%m/%d/%y",
comment = "T", check.names = FALSE, colClasses = colClasses)
这给出:
A B C
2015-05-29 21 96 276
2015-06-01 20 97 279
如果可以硬编码字段的数量,我们可以通过省略 count.fields
语句并将 n/2-1
替换为 2
来略微减少代码。
1a) 如果 header 行中可以有 T,则使用此代替:
L <- readLines(textConnection(Lines))[-2]
read.zoo(text = L, header = TRUE, sep = ",", format = "%m/%d/%y",
check.names = FALSE, colClasses = colClasses)
2) 使用上面计算的 colClasses
的 base R 的替代方案是:
DF <- read.csv(text = Lines, comment = "T", check.names = FALSE, colClasses = colClasses)
DF[[1]] <- as.Date(DF[[1]], "%m/%d/%y")
names(DF)[1] <- "Date"
2a) 类似地,如果第一行可以包含 T 则使用此代替,其中 L
来自 (1a),colClasses
来自(1).
DF <- read.csv(text = L, check.names = FALSE, colClasses = colClasses)
DF[[1]] <- as.Date(DF[[1]], "%m/%d/%y")
names(DF)[1] <- "Date"