置换data.frame R中的组

Leo*_*sar 0 r sample permutation

我有一个像这样的data.frame:

DqStr <- "Group   q        Dq       SD.Dq
1 -3.0 0.7351 0.0067
1 -2.5 0.6995 0.0078
1 -2.0 0.6538 0.0093
2 -3.0 0.7203 0.0081
2 -2.5 0.6829 0.0094
2 -2.0 0.6350 0.0112"
Dq1 <- read.table(textConnection(DqStr), header=TRUE)
Run Code Online (Sandbox Code Playgroud)

我想随机化组成员身份,但仅限于具有相同Dq1 $ q值的行

g <-unique(Dq1$q)
Dq2<- data.frame()
for(n in g)
{
  Dqq <- Dq1[Dq1$q==n,]
  Dqq$Group <-sample(Dqq$Group)
  Dq2 <- rbind(Dq2,Dqq)    
}
Run Code Online (Sandbox Code Playgroud)

这也可以通过plyr来完成

library(plyr)
ddply(Dq1,.(q), function(x) { x$Group <- sample(x$Group)
                              data.frame(x)})
Run Code Online (Sandbox Code Playgroud)

因为我必须重复这几千次,我想知道是否有更好(更快)的方法来做到这一点.

Fra*_*ank 5

如果我正确理解您的问题,此data.table解决方案也将起作用:

library(data.table)
Dq1 <- as.data.table(Dq1)
Dq1[, Group := sample(Group), by = q]
Run Code Online (Sandbox Code Playgroud)

增加罗伯特上面的基准:

library(plyr)
library(data.table)

your_code <- function() { g <-unique(Dq1$q); Dq2<- data.frame(); for(n in g) { Dqq <- Dq1[Dq1$q==n,]; Dqq$Group <-sample(Dqq$Group); Dq2 <- rbind(Dq2,Dqq) } }
plyr_code <- function() { ddply(Dq1,.(q), function(x) { x$Group <- sample(x$Group); data.frame(x)}) }
base_code <- function() { Dq1$Group <- with(Dq1, ave(Group, q, FUN = sample)) }
data.table_code <- function() { Dq1 <- as.data.table(Dq1); Dq1[, Group := sample(Group), by = q] }

library(microbenchmark)
microbenchmark(your_code(), plyr_code(), base_code(), data.table_code())
Run Code Online (Sandbox Code Playgroud)

结果:

    Unit: milliseconds
              expr      min       lq   median       uq      max neval
       your_code() 6.290822 6.771324 6.848123 6.966648 9.639748   100
       plyr_code() 3.124676 3.307456 3.356095 3.455422 4.564390   100
       base_code() 1.168874 1.301224 1.326055 1.348327 2.269652   100
 data.table_code() 1.124844 1.157866 1.180649 1.209577 1.419750   100
Run Code Online (Sandbox Code Playgroud)

对于数据集来说,这个小的data.table并不是很明显.但是如果你有很多行(如果你用fread你的数据作为data.table来读取),你会看到plyr上的显着加速,以及基本R的一些加速.所以不要采用这个基准认真.

编辑:改为使用as.data.table()而不是data.table(),根据Arun的评论.