如何仅为NON DISTINCT时间戳记取列值的中位数

时间:2016-09-29 04:45:13

标签: r dataframe dplyr xts tidyr

我正在尝试清理一些刻度数据。我的数据很长。当我将它转换为宽时它显示 Error: Duplicate identifiers for rows。时间列有几天的时间戳。 SYM列具有许多股票的股票代码。这是我的样本数据:

dput(jojo)
structure(list(Time = structure(c(1459481850, 1459481850, 1459482302, 
1459482305, 1459482305, 1459482307, 1459482307, 1459482309, 1459482312, 
1459482312, 1459482314, 1459482314, 1459482316, 1459482316, 1459482317, 
1459482317, 1459482318, 1459482319, 1459482319, 1459482320), class = c("POSIXct", 
"POSIXt"), tzone = "Asia/Calcutta"), PRICE = c(1371.25, 1371.25, 
1373.95, 1373, 1373, 1373.95, 1373.95, 1373.9, 1374, 1374, 1374.15, 
1374.15, 1374, 1374, 1373.85, 1373.85, 1372.55, 1374.05, 1374.05, 
1374.15), SIZE = c(39, 58, 5, 4, 7, 20, 5, 10, 21, 179, 10, 100, 
98, 78, 14, 11, 30, 10, 11, 39), SYM = c("A", "A", "A", "A", 
"A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "B", "B", 
"B", "B", "B")), .Names = c("Time", "PRICE", "SIZE", "SYM"), row.names = c(NA, 
20L), class = "data.frame")

我需要首先找到相同的时间戳,然后为这些时间戳取PRICE和SIZE的中位数,并用数据集中包含PRICE和SIZE中值的单行替换这些相同的时间戳行。但我的代码总结了整个列,而不是股票代码的相同时间戳行。这是我的尝试:

#Cleaning duplicate time stamps
tt<- jojo %>%group_by(SYM )%>% summarise(Time = ifelse(n() >= 2, median, mean))
#Making wide form
tt<-spread(tt, SYM, PRICE)

我收到此错误:

Error in eval(substitute(expr), envir, enclos) : Not a vector

请建议更正。如果我可以在不使用高频包的情况下进行清洁,那将是很好的。

1 个答案:

答案 0 :(得分:2)

您需要选择是否要使用dplyrxts范例。它们不能很好地协同工作,主要是因为dplyr期望data.frames和xts对象是矩阵。 dplyr还会屏蔽stats::lag泛型,这会阻止方法调度(例如,在顶层运行lag(.xts(1,1))将无法达到预期效果。)

使用xts范例解决此问题:

# create a function to convert to xts and take medians of the two columns
unDuplicate <- function(x) {
  # create xts object
  X <- xts(x[,c("PRICE","SIZE")], x[,"Time"])
  # set column names so they will be unique in wide format
  colnames(X) <- paste(colnames(X), x[1,"SYM"], sep = ".")
  # function to take median of each column
  colMedian <- function(obj, ...) {
    apply(obj, 2, median, ...)
  }
  # aggregate by seconds
  period.apply(X, endpoints(X, "seconds"), colMedian)
}
# now you can call the function on each symbol, then merge the results
do.call(merge, lapply(split(jojo, jojo$SYM), unDuplicate))
相关问题