我有兴趣找到一种方法来矢量化(使用ddply或其他一些应用函数)以下内容:
day = seq(0,100,20)
d = data.frame(id=rep(seq(1:10),each=length(day)))
d$s = rnorm(nrow(d),0,1)
d$diffS = NA
for(i in unique(d$id)) {
d$diffS[d$id==i] = c(0,diff(d$s[d$id==i]))
}
基本上我正在寻找一种更聪明的方法来通过ID获取数据帧的子集,应用一个返回向量的函数并将其添加回数据帧。我想也许“by”功能可行,但我无法弄明白。
答案 0 :(得分:7)
您可以尝试其中一个aggregating
功能
d$diffS <- with(d, ave(s, id, FUN=function(x) c(0, diff(x))))
或者
library(dplyr)
d %>%
group_by(id) %>%
mutate(diffS= c(0, diff(s)))
或者
library(data.table)#v1.9.5+
setDT(d)[, diffS:= c(0, diff(s)), by = id]
正如@Arun在评论中提到的那样,&#39; data.table&#39;的开发版本有shift
这会更有效率。安装devel版本的说明是here
setDT(d)[, diffS := s-shift(s, fill=0), by = id]
答案 1 :(得分:3)
这也可以通过以下方式实现
使用form_for(@my_model,:url=>'javascript:;')
ddply
或library('plyr')
out = ddply(d, .(id), mutate, diffs = c(0,diff(s)))
tapply
或d$diffs = unlist(tapply(d$s, d$id, function(x) c(0, diff(x))))
lapply
或out = do.call(rbind,
lapply(split(d, f = d$id),
function(x){x$diffs = c(0,diff(x$s)); x}))
sapply
答案 2 :(得分:3)
因为你提到了函数v1 <- c(" Class Dist Quantity Market Taxable/$ ",
" 4-2101 THIS LAND 28 108.85 216797 6352.00 ",
"99-9084 FIRE PROTECTION 9084 0.00 0 26.95 ",
"99-9093 COUNTY VALLEY SOIL 9093 0.00 0 6352.00 "
)
:
by
由于输出布局,建议不要这样做。它不利于附加数据框,
using_by <- with(d, by(s, id, FUN=function(x) c(0, diff(x))))
要将其修复为数据,应采取额外步骤:
id: 1
[1] 0.0000000 1.7884528 0.8135887 0.1891395 -0.6823383
[6] -2.6844915
---------------------------------------------
id: 2
[1] 0.0000000 -0.0258939 -0.8095359 0.5238898 -1.0345254
[6] 1.5432667