将随机选择的参与者的数据与dplyr相结合
我有以下数据帧“df”。 每个参与者(这里有10个参与者)都看到了几个刺激(这里有100个),并进行了测试 关于它的判断(这里是一个随机数)。对于每一种刺激,我都知道真相 答案(这里是一个随机数;每个刺激都有一个不同的数字,但总是如此) 所有参与者的答案都相同(NST)将随机选择的参与者的数据与dplyr相结合,r,performance,random,dplyr,combinations,R,Performance,Random,Dplyr,Combinations,我有以下数据帧“df”。 每个参与者(这里有10个参与者)都看到了几个刺激(这里有100个),并进行了测试 关于它的判断(这里是一个随机数)。对于每一种刺激,我都知道真相 答案(这里是一个随机数;每个刺激都有一个不同的数字,但总是如此) 所有参与者的答案都相同(NST) participant使用data.table和循环,我们可以得到10倍快的解决方案。 我的职能: minem <- function(n) { # n - simulation count require(data.
participant使用data.table
和循环,我们可以得到10倍快的解决方案。
我的职能:
minem <- function(n) { # n - simulation count
require(data.table)
participants_id <- unique(df$participant)
N <- length(unique(df$participant))
dt <- as.data.table(df)
setkey(dt, stimuli)
L <- list()
for (j in 1:n) {
corss <- rep(0, N)
for (i in 1:N) {
participants_x <- sample(participants_id, i)
xx <- dt[participant %in% participants_x,
.(mean_x = mean(judgment),
criterion = first(criterion)),
by = stimuli]
corss[i] <- cor(xx$mean_x, xx$criterion)
}
L[[j]] <- corss
}
unlist(L)
}
head(minem(10))
# [1] 0.13642499 -0.02078109 -0.14418400 0.04966805 -0.09108837 -0.15403185
Meir <- function(n) {
replicate(n, MyFun(df), simplify = FALSE) %>% bind_rows()
}
大约快10倍
system.time(minem(1000)) # ~19 sek
更新
如果您的数据大小和内存限制允许,则使用此方法可以更快地完成:
minem2 <- function(n) {
require(data.table)
participants_id <- unique(df$participant)
N <- length(unique(df$participant))
dt <- as.data.table(df)
setkey(dt, participant)
L <- lapply(1:n, function(x)
sapply(1:N, function(i)
sample(participants_id, i)))
L <- unlist(L, recursive = F)
names(L) <- 1:length(L)
g <- sapply(seq_along(L), function(x) rep(names(L[x]), length(L[[x]])))
L <- data.table(participant = unlist(L), .id = as.integer(unlist(g)),
key = "participant")
L <- dt[L, allow.cartesian = TRUE]
xx <- L[, .(mean_x = mean(judgment), criterion = first(criterion)),
keyby = .(.id, stimuli)]
xx <- xx[, cor(mean_x, criterion), keyby = .id][[2]]
xx
}
microbenchmark::microbenchmark(
Meir(100),
minem(100),
minem2(100),
times = 2, unit = "relative")
# Unit: relative
# expr min lq mean median uq max neval cld
# Meir(100) 316.34965 316.34965 257.30832 257.30832 216.85190 216.85190 2 c
# minem(100) 31.49818 31.49818 26.48945 26.48945 23.05735 23.05735 2 b
# minem2(100) 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 2 a
minem2首先,在外部循环中移动participants\u id=unique(Data$participant)
怎么样。我补充了你的建议。然而,它仍然很慢…@Meir有多慢?在我的机器上,100次复制需要11.5秒。我这样问是因为我很好奇为什么你需要它更快;您最终会将其扩展到更多复制或更高的N吗?这是你希望其他人在某个时候在自己的计算机上运行的东西,还是你只是担心自己的计算时间?我补充了一些精确性。理想情况下,我想要10000个模拟。1000次模拟需要2分钟,10000次大约需要20分钟。我想我的代码一定是出了问题,速度太慢了。谢谢。是否因为使用data.table而不是dplyr而更快?或者因为您使用for循环而不是apply?@Meir是因为data.table
。或多或少地使用lappy
与for
循环相同,因此通常不会影响性能。难以置信。我希望通过dplyr找到解决方案。data.table比dplyr快得令人惊讶。@Rtist最后一种方法没有这么快,因为data.table
,但因为我们在Lappy中不做任何计算,只选择样本索引。这回答了你的问题?如果是这样,那么你可能应该接受这个答案。。。
microbenchmark::microbenchmark(
Meir(10),
minem(10),
times = 10)
# Unit: milliseconds
# expr min lq mean median uq max neval cld
# Meir(10) 1897.6909 1956.3427 1986.5768 1973.5594 2043.4337 2048.5809 10 b
# minem(10) 193.5403 196.0426 201.4132 202.1085 204.9108 215.9961 10 a
system.time(minem(1000)) # ~19 sek
minem2 <- function(n) {
require(data.table)
participants_id <- unique(df$participant)
N <- length(unique(df$participant))
dt <- as.data.table(df)
setkey(dt, participant)
L <- lapply(1:n, function(x)
sapply(1:N, function(i)
sample(participants_id, i)))
L <- unlist(L, recursive = F)
names(L) <- 1:length(L)
g <- sapply(seq_along(L), function(x) rep(names(L[x]), length(L[[x]])))
L <- data.table(participant = unlist(L), .id = as.integer(unlist(g)),
key = "participant")
L <- dt[L, allow.cartesian = TRUE]
xx <- L[, .(mean_x = mean(judgment), criterion = first(criterion)),
keyby = .(.id, stimuli)]
xx <- xx[, cor(mean_x, criterion), keyby = .id][[2]]
xx
}
microbenchmark::microbenchmark(
Meir(100),
minem(100),
minem2(100),
times = 2, unit = "relative")
# Unit: relative
# expr min lq mean median uq max neval cld
# Meir(100) 316.34965 316.34965 257.30832 257.30832 216.85190 216.85190 2 c
# minem(100) 31.49818 31.49818 26.48945 26.48945 23.05735 23.05735 2 b
# minem2(100) 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 2 a