ddply分割并向每个组添加行

时间:2014-01-13 16:48:32

标签: r split plyr

我有一个df,如下所示,想要将df除以noms(唯一id),然后将x行添加到每个组中。然后我想重新组合。对于每个组,x将是不同的,并且将等于行数以将正整数增加到12(换句话说,x = 12的值 - 每个人的最高正整数)。

ddply似乎是明显的选择,但我在添加行时遇到了麻烦。我可以使用以下代码创建一个新列

x<-ddply(df,.(noms),transform, new_time=numbers)

但这并没有解决为每个人添加额外行的问题。我以为'变异'&#39;可能会为我做这件事,但除了我的逻辑在这里很糟糕,它不会添加行。

x<-ddply(df,.(noms),mutate, new_time=numbers+(tail(df$numbers-12)))

是否可以使用ddply添加行?甚至拆分?任何帮助将非常感激。先感谢您。

这里的df及以下是所需的输出。

df
   noms numbers
1  jane      -6
2  jane      -5
3  jane      -4
4  jane      -3
5  jane      -2
6  jane      -1
7  jane       1
8  jane       2
9  jane       3
10 jane       4
11 john      -2
12 john      -1
13 john       1
14 john       2
15 john       3
16 john       4
17 john       5
18 john       6
19 john       7
20 john       8
21 mary      -1
22 mary       1
23 mary       2
24 mary       3
25 mary       4
26 mary       5
27 mary       6
28 mary       7
29 mary       8
30 mary       9
31  tom      -4
32  tom      -3
33  tom      -2
34  tom      -1
35  tom       1
36  tom       2
37  tom       3
38  tom       4
39  tom       5
40  tom       6

所需的输出

dff
   noms nums new_times
1  jane   -6        -6
2  jane   -5        -5
3  jane   -4        -4
4  jane   -3        -3
5  jane   -2        -2
6  jane   -1        -1
7  jane    1         1
8  jane    2         2
9  jane    3         3
10 jane    4         4
11 jane   NA         5
12 jane   NA         6
13 jane   NA         7
14 jane   NA         8
15 jane   NA         9
16 jane   NA        10
17 jane   NA        11
18 jane   NA        12
19 john   -2        -2
20 john   -1        -1
21 john    1         1
22 john    2         2
23 john    3         3
24 john    4         4
25 john    5         5
26 john    6         6
27 john    7         7
28 john    8         8
29 john   NA         9
30 john   NA        10
31 john   NA        11
32 john   NA        12
33 mary   -1        -1
34 mary    1         1
35 mary    2         2
36 mary    3         3
37 mary    4         4
38 mary    5         5
39 mary    6         6
40 mary    7         7
41 mary    8         8
42 mary    9         9
43 mary   NA        10
44 mary   NA        11
45 mary   NA        12
46  tom   -4        -4
47  tom   -3        -3
48  tom   -2        -2
49  tom   -1        -1
50  tom    1         1
51  tom    2         2
52  tom    3         3
53  tom    4         4
54  tom    5         5
55  tom    6         6
56  tom   NA         7
57  tom   NA         8
58  tom   NA         9
59  tom   NA        10
60  tom   NA        11
61  tom   NA        12

修改

感谢@rrs的贡献。代码在玩具数据上运行良好,但在真实数据集上,弹出以下错误

Error in rep(NA, length(pootdf$new_numbers) - length(pootdf$time)) : 
  invalid 'times' argument

玩具数据和实际数据之间的唯一区别是大数据在大约400,000行时更大。两个名称变量都设置为因子,数字变量设置为整数。我已经将大型DF子集化为大约100行的更易于管理的大型DF,并且仍然出现错误。有谁知道会发生什么,以及如何解决这个问题?以下是追溯。

traceback()
7: .fun(piece, ...)
6: function (i) 
   {
       piece <- pieces[[i]]
       if (.inform) {
           res <- try(.fun(piece, ...))
           if (inherits(res, "try-error")) {
               piece <- paste(capture.output(print(piece)), collapse = "\n")
               stop("with piece ", i, ": \n", piece, call. = FALSE)
           }
       }
       else {
           res <- .fun(piece, ...)
       }
       progress$step()
       res
   }(1L)
5: .Call("loop_apply", as.integer(n), f, env)
4: loop_apply(n, do.ply)
3: llply(.data = .data, .fun = .fun, ..., .progress = .progress, 
       .inform = .inform, .parallel = .parallel, .paropts = .paropts)
2: ldply(.data = pieces, .fun = .fun, ..., .progress = .progress, 
       .inform = .inform, .parallel = .parallel, .paropts = .paropts)
1: ddply(pootdf, .(hai_dispense_number), AddRows)

1 个答案:

答案 0 :(得分:2)

我认为这会做你想做的事情:

AddRows <- function(df) {
  new_numbers <- seq(from = min(df$numbers), to = 12)
  new_numbers <- new_numbers[new_numbers != 0]
  noms <- rep(unique(df$noms), length(new_numbers))
  numbers <- c(df$numbers, rep(NA, length(new_numbers) - length(df$numbers)))

  return(data.frame(noms, numbers, new_numbers))
}

ddply(df, .(noms), AddRows)