按日期在R

时间:2015-07-23 17:33:18

标签: r

我有一些看起来像这样的数据:

Date        PX_SETTLE   CHG_NET_1D  Date.1      PX_SETTLE.1 CHG_NET_1D.1      Date.3
12/7/1988   91.07       0.03        12/7/1988   90.93       -0.02         12/7/1988
12/8/1988   91.09       0.02        12/8/1988   N/A         -0.02         12/8/1988
12/9/1988   91.1        0.01        12/9/1988   90.88        N/A          12/9/1988
12/12/1988  91.1        0           12/12/1988  90.86       -0.02         12/12/1988
12/15/1988  91.12       0.02        12/15/1988  90.76       -0.1          12/15/1988

这种模式还有几个列。

随着数据的进展,日期开始不对齐(这是原始数据)。我想要做的是:按日期(Date,Date.1,Date.3 .... Date.N)合并所有数据,并删除包含至少一个N / A值的行。

我从Bloomberg中提取了这些数据,因此每一行都没有共享相同的日期。最终你会看到像

这样的行
12/7/1988   91.07       0.03        12/8/1988   90.93       -0.02         12/6/1988

过去,我刚刚将数据框拆分为其组成部分(每个商品都有日期,价格和净变化),然后使用' merge'将它们逐个合并。我喜欢一气呵成,前进。

编辑:好的,我将excel中的原始日期列编辑为标准的明确格式。此外,我运行了以下内容:

for(i in 1:length(colnames(DF))) {
  if(!grepl("Date", colnames(DF))[i]) {
    DF[,i] <- as.numeric(as.character(DF[, i]))
  } else {
    DF[,i] <- as.Date(as.character(DF[, i]))
  }
}

现在我的日期属于班级&#39;日期&#39;我的号码是班级&#39;数字&#39;。我正在研究使用data.table。

1 个答案:

答案 0 :(得分:1)

你在评论中说你已经弄清楚了,但这对我来说是一个有用的练习题,所以我想我会继续发一个答案,以防它对别人有用,并希望找到如果有更有效的方法可以做到这一点。

我做了两个版本:一个假定列的集合是对同一个事物的不同观​​察,另一个假设列集代表您使用相同度量观察的不同组。

这是我使用的数据;最后一行包括不同的日期,以确保该过程适应这种情况:

Date    PX_SETTLE   CHG_NET_1D  Date.1  PX_SETTLE.1 CHG_NET_1D.1
12/7/1988   91.07   0.03    12/7/1988   90.93   -0.02
12/8/1988   91.09   0.02    12/8/1988   NA  -0.02
12/9/1988   91.1    0.01    12/9/1988   90.88   NA
12/12/1988  91.1    0   12/12/1988  90.86   -0.02
12/15/1988  91.12   0.02    12/15/1988  90.76   -0.1
12/16/1988  91.2    0.08    12/20/1988  90.96   0.20

单一实体的多项措施

此版本假设列的集合是对同一事物的不同观​​察(例如,特定日期跨多个交易所的特定商品的价格),因此最终您希望每个日期只有一行,其中列由集合索引观察(例如,来源)。

# If necessary, add an index value to first block of columns in df; see http://stackoverflow.com/questions/8898501/grepl-search-within-a-string-that-does-not-contain-a-pattern
names(df) <- c(paste0(names(df)[!grepl("\\.", names(df))], ".0"), names(df[grepl("\\.", names(df))])
# Make vector that will serve as index to columns in df
indx <- gsub(".*\\.", "", names(df))
# create separate dfs in workspace based on that index; see http://stackoverflow.com/questions/27501615/splitting-a-dataframe-by-column-name-indices
list2env(
    setNames(
        lapply(split(colnames(df), indx), function(x) df[x]),
            paste('df', sort(unique(indx)), sep="_")),
    envir=.GlobalEnv)
# Create function to scrub each df by simplifying Date name and setting is as key
fixit <- function(dataframe) {
    require(data.table)
    colnames(dataframe) <- sub("Date.*", "Date", colnames(dataframe))
    dataframe$Date <- as.Date(dataframe$Date, format="%m/%d/%Y")
    DT <- setkey(data.table(dataframe), Date)
    return(DT)
}
# Make a list of data frames in the workspace with names that fit the pattern created a couple of steps above
dflist <- Filter(function(x) is(x, "data.frame"), mget(ls(pattern = "_[0-9]")))
# Apply the scrubbing function to the items in that list, returning scrubbed list
newdflist <- lapply(dflist, fixit)
# Merge the elements of that new list, keeping all values and keying on Date
newdf <- Reduce(function(...) merge(..., all=TRUE), newdflist)

以下是该过程的结果。非日期变量的后缀表示不同的观察集:

> newdf
         Date PX_SETTLE.0 CHG_NET_1D.0 PX_SETTLE.1 CHG_NET_1D.1
1: 1988-12-07       91.07         0.03       90.93        -0.02
2: 1988-12-08       91.09         0.02          NA        -0.02
3: 1988-12-09       91.10         0.01       90.88           NA
4: 1988-12-12       91.10         0.00       90.86        -0.02
5: 1988-12-15       91.12         0.02       90.76        -0.10
6: 1988-12-16       91.20         0.08          NA           NA
7: 1988-12-20          NA           NA       90.96         0.20

多个实体的常用度量

现在让我们假设每个列的列代表一个独特的实体,如股票代码,在重叠的日期集上以相同的方式测量。这里我们将重复上面的大部分过程,除了现在擦洗功能不会打扰列表元素,因为我们希望允许它们重复(跨组)。相反,该函数将添加一个索引变量,并将列表元素中的所有变量名称简化为通用格式,以便于最后合并。

names(df) <- c(paste0(names(df)[!grepl("\\.", names(df))], ".0"), names(df[grepl("\\.", names(df))])
indx <- gsub(".*\\.", "", names(df))
list2env(
     setNames(
       lapply(split(colnames(df), indx), function(x) df[x]),
           paste('df', sort(unique(indx)), sep="_")), 
     envir=.GlobalEnv)
dflist <- Filter(function(x) is(x, "data.frame"), mget(ls(pattern = "_[0-9]")))
fixit2 <- function(dataframe) {
    z <- dataframe
    z[,"index"] <- unlist(strsplit(colnames(z)[1], "\\."))[2]
    colnames(z) <- sub("\\.[0-9]", "", colnames(z))
    return(z)
}
newdflist2 <- lapply(dflist, fixit2)
newdf2 <- Reduce(function(...) merge(..., all=TRUE), newdflist2)
newdf2 <- newdf2[order(newdf2$index, newdf2$Date),]

以下是输出的结果:

> newdf2
         Date PX_SETTLE CHG_NET_1D index
2  1988-12-07     91.07       0.03     0
3  1988-12-08     91.09       0.02     0
6  1988-12-09     91.10       0.01     0
8  1988-12-12     91.10       0.00     0
10 1988-12-15     91.12       0.02     0
11 1988-12-16     91.20       0.08     0
1  1988-12-07     90.93      -0.02     1
4  1988-12-08        NA      -0.02     1
5  1988-12-09     90.88         NA     1
7  1988-12-12     90.86      -0.02     1
9  1988-12-15     90.76      -0.10     1
12 1988-12-20     90.96       0.20     1

这两种方法都可以通过管道或嵌套一些后续步骤来简化。