【发布时间】:2020-12-22 14:38:13
【问题描述】:
我正在 R 中进行一些模拟。但是,我的代码运行速度非常慢,因此不适合高 N 和大量 sims 。我已将瓶颈确定为以下功能(见下文)。它需要一个 s tibble 列表作为输入。基本上,在组 g 内(每个 g_id 两行)我想将我的参数值(概率)分配给组内的第一行(g_first == 1),假设变量 A 和 B 的值匹配特定模式g 内(即手工编码两个分类变量之间的交互)。 A 和 B 的值也存储为 1/0 变量(例如,如果 B 为 x,则 B_x 取值为 1)。
我尝试使用 data.tables 列表而不是 tibbles 作为输入,但实际上它进一步减慢了它的速度(也许 bc 下面的子集对于 data.tables 来说很慢。此外,我不知道如何为 setkey() data.tables 列表)。
根据请求,我在此链接下上传了一个示例 df(包含 100 个模拟小标题的列表):https://ufile.io/dsax7us8。通过 lapply(df, assign_p) 调用该函数。在下面的代码中,您还可以快速浏览 df 列表的元素之一。
#a quick glance on the data structure
dput(head(df[[1]]))
structure(list(p_id = c(1L, 1L, 1L, 1L, 2L, 2L), g_id = c(1L,
1L, 2L, 2L, 3L, 3L), pr_id = 1:6, g_first = c(1, 0, 1, 0, 1,
0), A = c(1, 0, 1, 0, 0, 1), B = c("x", "z", "x", "x", "z", "z"
), C = c(1, 1, 1, 1, 1, 0), A_0 = c(0, 1, 0, 1, 1, 0), A_1 = c(1,
0, 1, 0, 0, 1), B_x = c(1, 0, 1, 1, 0, 0), B_z = c(0, 1, 0, 0,
1, 1), C_0 = c(0, 0, 0, 0, 0, 1), C_1 = c(1, 1, 1, 1, 1, 0)), row.names = c(NA,
-6L), class = c("tbl_df", "tbl", "data.frame"))
dput(head(df[[2]]))
structure(list(p_id = c(1L, 1L, 1L, 1L, 2L, 2L), g_id = c(1L,
1L, 2L, 2L, 3L, 3L), pr_id = 1:6, g_first = c(1, 0, 1, 0, 1,
0), A = c(0, 0, 1, 0, 1, 0), B = c("x", "z", "z", "x", "x", "z"
), C = c(1, 1, 1, 0, 1, 0), A_0 = c(1, 1, 0, 1, 0, 1), A_1 = c(0,
0, 1, 0, 1, 0), B_x = c(1, 0, 0, 1, 1, 0), B_z = c(0, 1, 1, 0,
0, 1), C_0 = c(0, 0, 0, 1, 0, 1), C_1 = c(1, 1, 1, 0, 1, 0)), row.names = c(NA,
-6L), class = c("tbl_df", "tbl", "data.frame"))
#params
A_10_B_xx <- 0.04
A_10_B_xz <- 0.04
A_10_B_zz <- 0.003
A_10_B_zx <- 0.003
A_01_B_xx <- -0.04
A_01_B_xz <- -0.04
A_01_B_zz <- -0.003
A_01_B_zx <- -0.003
assign_p <- function(df) {
df$p <- NA_real_
g <- max(df$g_id)
for (i in 1:g) {
#generate logical checks
A_11 = df[df$g_id == i & df$g_first == 1, "A_1"]
A_10 = df[df$g_id == i & df$g_first == 0, "A_1"]
A_01 = df[df$g_id == i & df$g_first == 1, "A_0"]
A_00 = df[df$g_id == i & df$g_first == 0, "A_0"]
B_x1 = df[df$g_id == i & df$g_first == 1, "B_x"]
B_x0 = df[df$g_id == i & df$g_first == 0, "B_x"]
B_z1 = df[df$g_id == i & df$g_first == 1, "B_z"]
B_z0 = df[df$g_id == i & df$g_first == 0, "B_z"]
#multiply logical checks
A_10_B_xx_out <- A_10_B_xx * A_11 * A_00 * B_x1 * B_x0
A_10_B_xz_out <- A_10_B_xz * A_11 * A_00 * B_x1 * B_z0
A_10_B_zz_out <- A_10_B_zz * A_11 * A_00 * B_z1 * B_z0
A_10_B_zx_out <- A_10_B_zx * A_11 * A_00 * B_z1 * B_x0
A_01_B_xx_out <- A_01_B_xx * A_01 * A_10 * B_x1 * B_x0
A_01_B_xz_out <- A_01_B_xz * A_01 * A_10 * B_x1 * B_z0
A_01_B_zz_out <- A_01_B_zz * A_01 * A_10 * B_z1 * B_z0
A_01_B_zx_out <- A_01_B_zx * A_01 * A_10 * B_z1 * B_x0
#add matches to 0.5 and assign to column p
df[df$g_id == i &
df$g_first == 1, "p"] <- 0.50 +
A_10_B_xx_out +
A_10_B_xz_out +
A_10_B_zz_out +
A_10_B_zx_out +
A_01_B_xx_out +
A_01_B_xz_out +
A_01_B_zz_out +
A_01_B_zx_out
}
df
}
【问题讨论】:
-
欢迎来到stackoverflow!请向我们提供一些虚拟数据(例如使用
dput)。在处理它们之前,rbindlistdata.tables 可能会有所帮助。此外,您可能需要检查fcase()自 data.table v1.13.0 (24 Jul 2020) 起可用 -
感谢您的更新 - 但能否请您粘贴
dput(my_tibble_1)或dput(head(my_tibble_1))的输出,以便我们无需从外部来源下载文件即可查看结构?谢谢! Here你可以找到一些相关信息。 -
您能否详细说明 A (1,0) B (x,z) 必须在每个 g_id 中匹配的模式?我认为您的大部分代码可以简化为按组进行的简单聚合(请参阅第 2 章here)。
-
我想对交互效果进行编码:考虑到 A 和 B 采用特定的值组合,选择 g(group_id==1 或 group_id==0)的概率。 Y 将在下一步使用此处生成的 p 生成,此处省略,因为它似乎与问题无关(即瓶颈在其他地方)。感谢这些提示,我会检查一下并尝试一下。
-
我会使用您的参数创建一个查找表,并将其与当前数据集连接起来,然后进行计算。
标签: r loops data.table subset tibble