R 使用';由'-样式应用函数,但引用其他子集
全部, 考虑一个简单的问题:R 使用';由'-样式应用函数,但引用其他子集,r,merge,R,Merge,全部, 考虑一个简单的问题: 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] <-
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
set.seed(1)#如果生成样本数据,设置种子会很有帮助
idx您可以将该表与其自身合并。
特别是如果数据很大,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 ]
#将数据放入data.table,通过idx键入
库(数据表)
tmpDT这里有一个基本方法:
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)
dal这里有一个使用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)
FUN您是否意识到for循环的第一次迭代是向delt分配8个非NA任务?我认为无论是by
还是lappy(split(.),FUN)
都会失败,因为您正在为一行组的“下边框”后面的行编制索引。感谢您的解决方案和反馈@Grothendieck的方法对我来说是最快、最简洁的。@Aaron,没问题。很高兴你的问题解决了。请不要忘了在Gabor的解决方案上打勾