3

全部,

考虑一个简单的问题:

set.seed(1)   # if generating sample data, it's helpful to set a seed
idx <- rep(1:4,each=4)
c1 <- rnorm(16)
c2 <- rnorm(16)
tmp <- data.frame(idx,c1,c2)

for(i in 2:4){
    rows <- which(idx==i)
    tmp$delt[rows] <- (tmp$c2[min(rows)-1] - tmp$c1[min(rows)])/tmp$c2[min(rows)-1]
}

tmp

我想知道是否有一种有效的方法可以使用 apply-class 函数生成 delt 列。此示例运行良好,但在大型数据集上实施时可能会陷入困境。

干杯

4

3 回答 3

3

这是使用的解决方案ave

FUN <- function(i) { 
   i1 <- i[1]
   if (i1 > 1) 1 - tmp$c1[i1] / tmp$c2[i1 - 1] else NA
}
tmp$delt <- ave(1:nrow(tmp), tmp$idx, FUN = FUN)
于 2013-04-01T00:26:13.020 回答
2

您可以将表格与自身合并。特别是如果数据很大,data.table 会很快

# put your data into a data.table, keying by idx
library(data.table)
tmpDT <- data.table(idx,c1,c2, key="idx")


# merge to itself and calculate, using tail() and head()
tmpDT[ tmpDT[, list(c2prev = tail(c2, 1)), by=(idx+1)]
       , delt :=  (c2prev - head(c1, 1)) / c2prev  ]
于 2013-03-31T23:16:09.833 回答
0

这是一个基本方法:

dal <- c(FALSE, as.logical(diff(idx)))
dal_s <- c(as.logical(diff(idx)), FALSE)
d <- data.frame(idx=2:4,  delt=1-tmp$c1[dal]/tmp$c2[dal_s])
merge(tmp, d, all=TRUE)

请注意(x - y)/x= 1 - y/x。如有必要,您可以使用上面的前一个表达式。

于 2013-03-31T23:28:47.097 回答