Excel或R:从多个来源准备时间序列?

Mat*_*ert 7 r time-series

最近,我经常不得不在同一分析中处理来自多个.csv源的时间序列数据.让我们假设所有系列都是常规的季度系列(两者之间没有缺失值).通常,原始.csv数据包含日期列和1-3个变量.不幸的是,这个系列在.csv文件中的长度并不相同.

我开始在R中组织我的数据集,结果发现包含大量window()命令的大混乱.另外,我必须在将它们转换为ts()对象之前连接NAs和原始系列,因为我发现连接(多变量)ts()对象非常直观.请注意,我添加NA的原因是我希望所有系列都具有相同的长度.当然我可以修剪较长的那些,但是当我不使用较短的系列时我最终会松开观察.

我想过编写一个函数来读取.csv文件并使用它的日期列来创建ts()对象,并且可能使用另一个函数合并所有单个系列,以便在数据丢失时创建包含NA的多变量系列.我发现自己一直在切换数据类型,阅读ts和动物园手册 - 我简直无法相信它是那么复杂.

我真的认为这个问题非常普遍,并且考虑过excel中的准备工作.我的意思是我真的很讨厌excel,但是这次我想知道更有经验的useRs做什么?R还是Excel?

编辑:添加了一些示例性数据(需要聚合每日数据)file1:

27.05.11;5965.95
26.05.11;5947.06
25.05.11;5942.82
24.05.11;5939.98
Run Code Online (Sandbox Code Playgroud)

file2(没有日期col,但我知道开始和频率)

Germany;Switzerland;USA;OECDEurope
69,90974;61,8241;55,60966;64,96157
67,0394;62,18966;56,47361;64,15152
70,56651;63,6347;56,87237;65,43568
Run Code Online (Sandbox Code Playgroud)

文件3:

1984-04-01,33.3238396624473
1984-07-01,63.579833082501
1984-10-01,35.8375401560349
Run Code Online (Sandbox Code Playgroud)

我承认示例性数据确实有助于说明问题,但它是一种最佳实践类型的问题,可以解决比我更有经验的用户.您如何为多变量ts分析准备数据?

Jos*_*ich 7

我一直在R做这个.您可能会发现在Excel中更容易,但如果您的数据发生更改,则必须再次执行相同的过程.使用R可以更轻松地更新和重现结果.

使用动物园yearmonyearqtr索引类分别处理月度或季度频率变得非常容易.在带有yearqtr索引的zoo对象中获取数据后,您所要做的就是合并所有对象.

这是您的示例数据:

Lines1 <-
"27.05.11;5965.95
26.05.11;5947.06
25.05.11;5942.82
24.05.11;5939.98"
f1 <- read.csv2(con <- textConnection(Lines1), header=FALSE)
close(con)

Lines2 <-
"Germany;Switzerland;USA;OECDEurope
69,90974;61,8241;55,60966;64,96157
67,0394;62,18966;56,47361;64,15152
70,56651;63,6347;56,87237;65,43568"
f2 <- read.csv2(con <- textConnection(Lines2), header=TRUE)
close(con)

Lines3 <-
"1984-04-01,33.3238396624473
1984-07-01,63.579833082501
1984-10-01,35.8375401560349"
f3 <- read.csv(con <- textConnection(Lines3), header=FALSE)
close(con)
Run Code Online (Sandbox Code Playgroud)

下面的示例假定第一个文件的开始日期是1984Q2,第二个文件的开始日期是1984Q4.您可以看到merge.zoo为您调整所有日期.在zoo对象中对齐所有内容后,可以使用该as.ts方法创建mts对象.

z1 <- zoo(f1[,-1], as.Date(f1[,1], "%d.%m.%y"))
z2 <- zoo(f2, as.yearqtr("1984Q4")+(seq_len(NROW(f1))-1)/4)
z3 <- zoo(f3[,-1], as.yearqtr(as.Date(f3[,1])))

library(xts)
# Use xts::apply.quarterly to aggregate series with higher periodicity.
# Here I just take the last obs but you could use another function (e.g. mean).
z1 <- apply.quarterly(z1, last)
index(z1) <- as.yearqtr(index(z1))  # convert the index to yearqtr

(Z <- merge(z1,z2,z3))
#         z1      Germany  Switzerland USA      OECDEurope z3
# 1984 Q2 <NA>    <NA>     <NA>        <NA>     <NA>       33.32383
# 1984 Q3 <NA>    <NA>     <NA>        <NA>     <NA>       63.57983
# 1984 Q4 <NA>    69.90974 61.8241     55.60966 64.96157   35.83754
# 1985 Q1 <NA>    67.0394  62.18966    56.47361 64.15152   <NA>
# 1985 Q2 <NA>    70.56651 63.6347     56.87237 65.43568   <NA>
# 1985 Q3 <NA>    69.90974 61.8241     55.60966 64.96157   <NA>
# 2011 Q2 5965.95 <NA>     <NA>        <NA>     <NA>       <NA>

# Note that ts will create an object with a observation for every period,
# even if all the columns are missing.
TS <- as.ts(Z)
Run Code Online (Sandbox Code Playgroud)


And*_*rie 6

我对这类问题的策略是:

  1. 将每个数据源读入标准data.frame
  2. 清理每个data.frame,即将数据转换为所需格式,处理缺失值等.
  3. 合并或加入标准data.frame
  4. 执行任何聚合数据清理,例如添加空行,删除重复项等.
  5. 然后才将数据传递到下一步,例如转换为ts对象,绘制它等.

使用您的示例数据:

v1 <- "27.05.11;5965.95
26.05.11;5947.06
25.05.11;5942.82
24.05.11;5939.98"

v2 <- "Germany;Switzerland;USA;OECDEurope
69,90974;61,8241;55,60966;64,96157
67,0394;62,18966;56,47361;64,15152
70,56651;63,6347;56,87237;65,43568"


v3 <- "1984-04-01,33.3238396624473
1984-07-01,63.579833082501
1984-10-01,35.8375401560349"

# Read and clean data
dat1 <- read.table(textConnection(v1), header=FALSE, sep=";", dec=".")
names(dat1) <- c("date", "V1")
dat1$date <- as.Date(dat1$date, format="%d.%m.%y")
dat1

dat2 <- read.table(textConnection(v2), header=TRUE, sep=";", dec=",")
dat2$date <- seq(as.Date("2011/1/1"), by="3 months", length.out=3)
dat2

dat3 <- read.table(textConnection(v3), header=FALSE, sep=",", dec=".")
names(dat3) <- c("date", "V2")
dat3$date <- as.Date(dat3$date)
dat3

# Merge separate data.frames.
# I use join() in package plyr, you may wish to use merge(), rbind.fill, etc
library(plyr)
join(join(dat1, dat2, type="full"), dat3, type="full")
Run Code Online (Sandbox Code Playgroud)

结果:

         date      V1  Germany Switzerland      USA OECDEurope       V2
1  2011-05-27 5965.95       NA          NA       NA         NA       NA
2  2011-05-26 5947.06       NA          NA       NA         NA       NA
3  2011-05-25 5942.82       NA          NA       NA         NA       NA
4  2011-05-24 5939.98       NA          NA       NA         NA       NA
5  2011-01-01      NA 69.90974    61.82410 55.60966   64.96157       NA
6  2011-04-01      NA 67.03940    62.18966 56.47361   64.15152       NA
7  2011-07-01      NA 70.56651    63.63470 56.87237   65.43568       NA
8  1984-04-01      NA       NA          NA       NA         NA 33.32384
9  1984-07-01      NA       NA          NA       NA         NA 63.57983
10 1984-10-01      NA       NA          NA       NA         NA 35.83754
Run Code Online (Sandbox Code Playgroud)