【问题标题】:Optimization of for loop in RR中for循环的优化
【发布时间】:2019-08-13 07:41:19
【问题描述】:

我正在尝试优化我的 R 代码中的 for 循环。 概括: 我有一个包含 4700 万行和 4 列的数据表(由代码中的“nvars”指定)。 我想比较每列中的逐行值,如果任何两个相等,则将删除标志设置为 1,否则设置为 0。

我需要删除所有 4 列中至少有两个值相等的行。 (所有列中的值都是数字,例如 1,2,3...)

我尝试使用矢量化进行优化,但仍需要约 1.5 小时(大约)

这可以进一步优化吗?

test2 <- as.data.table(test2)
delete_output <- numeric(nrow(test2))
for (i in 1:nrow(test2)){
  for (j in 1:(nvars-1)){
    k=j+1
    if (test2[i,..j] == test2[i,..k]){
      delete_output[i] <- 1
     next
   } 
  }
 }

如果特定行中的任何两个值相等,则应将删除标志分配为 1。

我的文件应该看起来像图片中的那个。这是 3 个输入变量和相应的输出变量(删除)的示例。检查是否所有 V1、V2、V3 对于特定行都是唯一的,删除标志等于 0,否则为 1。

【问题讨论】:

  • 你能提供一个测试数据集吗?例如数据的一个子集。
  • test2[apply(test2, 1, function(x) all(table(x)==1)), ]
  • @jogo 如果我没记错的话,如果所有值都等于 1,这将起作用。我应该早点发布输入文件。您能否检查一下您的解决方案是否适用于我提供的输入数据?
  • @Ashu 请使用dput(...) 的输出来显示您的数据。你需要额外的列吗?我的代码中的逻辑是只选择那些所有元素都是唯一的行。

标签: r for-loop optimization


【解决方案1】:

我们可以使用apply(但我担心它可能不够快)并检查any duplicated 的值。

df$delete <- +(apply(df, 1, function(x) any(duplicated(x))))

df
#   V1 V2 V3 V4 delete
#1   3  3  3  1      1
#2   1  4  4  3      1
#3   2  2  1  4      1
#4   2  2  3  3      1
#5   2  4  4  2      1
#6   1  3  2  4      0
#7   1  1  1  3      1
#8   4  2  1  1      1
#9   3  4  2  2      1
#10  1  2  2  4      1

数据

set.seed(1432)
df <- as.data.frame(matrix(sample(1:4, 40, replace = TRUE), ncol = 4))

【讨论】:

  • 太棒了!这就像一个魅力!我的所有数据(4700 万行)所用时间不超过 2 分钟。
【解决方案2】:

你可以这样做:

set.seed(1432)
test2 <- as.data.frame(matrix(sample(1:4, 40, replace = TRUE), ncol = 4))
test2
test2[apply(test2, 1, function(x) all(table(x)==1)), ]

这将只选择那些所有元素都是唯一的行。
如果您需要额外的列,您可以这样做:

set.seed(1432)
test2 <- as.data.frame(matrix(sample(1:4, 40, replace = TRUE), ncol = 4))
test2
test2$delete <- !apply(test2, 1, function(x) all(table(x)==1))
test2

【讨论】:

    猜你喜欢
    • 2017-09-20
    • 1970-01-01
    • 2017-09-26
    • 2018-04-06
    • 2018-11-24
    • 1970-01-01
    • 2021-04-23
    • 2011-08-30
    • 1970-01-01
    相关资源
    最近更新 更多