如何对每个ID应用函数后返回向量的“for”循环进行向量化

时间:2015-06-08 18:49:20

标签: r

我有兴趣找到一种方法来矢量化(使用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”功能可行,但我无法弄明白。

3 个答案:

答案 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