R-ddply with循环遍历每一行

时间:2015-02-25 18:08:41

标签: r function loops plyr

我需要获取每一行的历史记录。 如果我的表是:

aa<-data.frame(tel=c(1,1,1,1,2,2,2,2,3,3), hora=c(1,2,4,4,1,1,3,4,1,2), 
               intentos=c(1,5,1,4,9,2,7,8,8,1), contactos=c(0,1,0,0,0,1,0,1,0,1))

我需要为每个tel获取一个“intentos”的趋势变量:对于instace实际值/先前值,但对于每一行。第一个电话的created1 = c(NA,5 / 1,1 / 5,4 / 1)

我想要的表是:

    tel hora    intentos    contactos   created1
1   1   1   1   0   NA
2   1   2   5   1   5
3   1   4   1   0   0.2
4   1   4   4   0   4
5   2   1   9   0   NA
6   2   1   2   1   0.222222222
7   2   3   7   0   3.5
8   2   4   8   1   1.142857143
9   3   1   8   0   NA
10  3   2   1   1   0.125

我知道我可以做以下事情:

library(plyr)
ddply(aa, .(tel), mutate, mean_hora=mean(hora), min_hora=min(hora))

但是我怎么能引入循环来得到描述的结果呢?

我尝试创建一个传递给ddply的函数:

g<-function (tbl) {x<-data.frame(tbl)
                   for (i in 2:length(tbl) ){ 
                     print(paste0(i-1))
                     print(tbl[i-1])
                        x[i,1]<-                 
                        tbl[i]/tbl[i-1] }
                   return (x)}

如果我在矢量上运行thiis,它就可以了。 所以我试着将它传递给ddply函数:

library(plyr)
ddply(aa, .(tel), mutate, mean_hora=mean(hora), min_hora=min(hora), created1=g(hora))

但是我收到以下错误:

  

错误:与STRSXP不兼容

我的方法(传递一个函数来评估每个向量)是好的吗?

1 个答案:

答案 0 :(得分:1)

这应该可以解决问题:

aa %>% 
  group_by(tel) %>% 
  mutate(lagged_intentos=lag(intentos)) %>% 
  mutate(created1=intentos/lagged_intentos) %>% 
  select(-lagged_intentos)



   tel hora intentos contactos  created1
1    1    1        1         0        NA
2    1    2        5         1 5.0000000
3    1    4        1         0 0.2000000
4    1    4        4         0 4.0000000
5    2    1        9         0        NA
6    2    1        2         1 0.2222222
7    2    3        7         0 3.5000000
8    2    4        8         1 1.1428571
9    3    1        8         0        NA
10   3    2        1         1 0.1250000

如果要对数据集中的所有其他变量执行此操作,请执行以下操作:

aa %>% 
  group_by(tel) %>% 
  mutate_each(funs(new=./lag(.)))


   tel     hora  intentos contactos
1    1       NA        NA        NA
2    1 2.000000 5.0000000       Inf
3    1 2.000000 0.2000000         0
4    1 1.000000 4.0000000       NaN
5    2       NA        NA        NA
6    2 1.000000 0.2222222       Inf
7    2 3.000000 3.5000000         0
8    2 1.333333 1.1428571       Inf
9    3       NA        NA        NA
10   3 2.000000 0.1250000       Inf

或者,如果只是变量的一个子集:

aa %>% 
  group_by(tel) %>% 
  mutate_each(funs(new=./lag(.)),hora,intentos)


   tel     hora  intentos contactos
1    1       NA        NA         0
2    1 2.000000 5.0000000         1
3    1 2.000000 0.2000000         0
4    1 1.000000 4.0000000         0
5    2       NA        NA         0
6    2 1.000000 0.2222222         1
7    2 3.000000 3.5000000         0
8    2 1.333333 1.1428571         1
9    3       NA        NA         0
10   3 2.000000 0.1250000         1

不幸的是,我认为dplyr中的当前错误是它用变异变量覆盖变量。您可以将它们添加回来:

aa %>% 
  group_by(tel) %>% 
  mutate_each(funs(new=./lag(.)),hora,intentos) %>% 
  cbind(aa,.) %>% 
  data.frame %>% 
  select(-tel.1) 

   tel hora intentos contactos   hora.1 intentos.1 contactos.1
1    1    1        1         0       NA         NA           0
2    1    2        5         1 2.000000  5.0000000           1
3    1    4        1         0 2.000000  0.2000000           0
4    1    4        4         0 1.000000  4.0000000           0
5    2    1        9         0       NA         NA           0
6    2    1        2         1 1.000000  0.2222222           1
7    2    3        7         0 3.000000  3.5000000           0
8    2    4        8         1 1.333333  1.1428571           1
9    3    1        8         0       NA         NA           0
10   3    2        1         1 2.000000  0.1250000           1