我有一些看起来像这样的数据:
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。
答案 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
这两种方法都可以通过管道或嵌套一些后续步骤来简化。