gpt4 book ai didi

r - 更快地实现对所有可能组合的过滤

转载 作者:行者123 更新时间:2023-12-04 19:25:49 26 4
gpt4 key购买 nike

考虑我有一个这样的数据框,

set.seed(1)

q<-100

df <- data.frame(Var1 = round(runif(q,1,50)),
Var2 = round(runif(q,1,50)),
Var3 = round(runif(q,1,50)),
Var4 = round(runif(q,1,50)))
attach(df)

正如您所意识到的, q代表设置数据框中每列的长度。

我想过滤所有可能的列组合。它可以是任何东西。假设我正在寻找前两列的总和与后两列的总和的除法是否大于 1。

使用 expand.grid() 实现这一目标的一件事功能。
a <- Sys.time()

expanded <- expand.grid(Var1, Var2, Var3, Var4)

Sys.time() - a

Time difference of 8.31997 secs


expanded <- expanded[rowSums(expanded[,1:2])/ rowSums(expanded[,3:4])>1,]

不过需要很多时间!为了让它更快,我试着用 rep.int() 来回答这个问题。函数在 this问题并设计了我自己的功能。
myexpand <- function(...) {

sapply(list(...),function(y) rep.int(y, prod(lengths(list(...)))/length(y)))

}

但它又没有那么有希望了。与我的预期和 expand.grid 相比,需要更多时间并且,如果我设置一个更大的 q ,就变成噩梦了!

在应用 expand.grid 之前,是否有适当的方法可以通过矩阵运算更快地(1-2 秒)实现这一目标?或 myexpand .而且,我想知道使用像 R 这样的解释性语言是否是一个弱点......软件建议也是可以接受的。

最佳答案

对于此特定条件(即总和的比率 > 1),您可能需要考虑使用 data.table包裹:

system.time({
#generate permutations of Var1 & Var2 and Var3 & Var4
DT12 <- DT[, CJ(Var1=Var1, Var2=Var2, unique=TRUE)][, s12 := Var1 + Var2]
DT34 <- DT[, CJ(Var3=Var3, Var4=Var4, unique=TRUE)][, s34 := Var3 + Var4]

#perform a non-equi join
DT12[DT34, on=.(s12>s34), allow.cartesian=TRUE,
.(Var1=x.Var1, Var2=x.Var2, Var3=i.Var3, Var4=i.Var4)][, s12:=NULL]
})

定时:
   user  system elapsed 
0.02 0.06 0.08

输出:
         Var1 Var2 Var3 Var4
1: 2 5 2 4
2: 4 3 2 4
3: 5 2 2 4
4: 2 6 2 4
5: 4 4 2 4
---
1753416: 50 49 49 48
1753417: 50 50 49 48
1753418: 50 49 49 49
1753419: 50 50 49 49
1753420: 50 50 49 50

数据:
library(data.table)
set.seed(1)
q <- 100
DT <- data.table(Var1 = round(runif(q,1,50)),
Var2 = round(runif(q,1,50)),
Var3 = round(runif(q,1,50)),
Var4 = round(runif(q,1,50)))

编辑:对于正数的总和,您可以使用以下方法(警告:它不会比使用 Rcpp 方法快)。
system.time({
S <- DT[, .(UB=90 - Var1, C1=Var1)]
for (k in 2:4) {
S <- DT[S, on=paste0("Var", k, "<UB"), allow.cartesian=TRUE,
mget(c(names(S), paste0("x.Var", k)))]
setnames(S, paste0("x.Var", k), paste0("C", k))
S[, UB := UB - get(paste0("C",k))]
}
S[, UB := NULL][rowSums(S)>30L]
})

定时:
   user  system elapsed 
3.48 4.06 3.51

输出, S :
> S
C1 C2 C3 C4
1: 14 33 14 6
2: 14 33 14 25
3: 14 33 14 24
4: 14 33 14 19
5: 14 33 14 10
---
34914725: 31 39 3 8
34914726: 31 39 3 8
34914727: 31 39 3 9
34914728: 31 39 3 16
34914729: 31 39 3 8

关于r - 更快地实现对所有可能组合的过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57457590/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com