【问题标题】:Add column to data frame based on long list and values in another column is too slow根据长列表将列添加到数据框中,另一列中的值太慢
【发布时间】:2020-10-11 15:17:33
【问题描述】:

我正在使用 apply() 和 mutate 向数据框添加一个新列。有用。不幸的是,它非常慢。我有 24M 行,我正在根据 long(58 项)中的值添加列。较小的列表是可以忍受的。不再。 这是我的例子

large_df <-data.frame(A=(1:4),
                   B= c('a','b','c','d'),
                  C= c('e','f','g','h')) 
long_list = c('e','f','g')

large_df =mutate (large_df, new_C = apply(large_df[,2:3], 1, 
                 function(r) any(r %in% long_list)))


新列 (new_C) 将读取 True 或 False。它有效,但我正在寻找一种快速的替代方案。

非常感谢。 塞尔希

Bonus Q。我不能只在 apply() 中选择一列,需要范围。为什么?

【问题讨论】:

  • 考虑使用“data.table”,它对于大型数据集来说相当快。如果您想使用“tidyverse”,映射列表可能会有所帮助,但很难理解您要做什么。如果您添加一些示例数据(“dput()”),其他人可能会发现更容易为您提供帮助。
  • 在 R 中动态添加列/行通常非常慢,因为在每个步骤中都会复制完整的数据,从而使其成为 O(n^2) 例程。你能以某种方式预先计算所需的列数吗?在这种情况下,您可以分配整个 data.frame,随后只需将值分配给已分配的内存。这将数据添加降低到 O(n) 运行时复杂度。
  • 谢谢克尼特。我试过'data.table'包,它加快了很多步骤。此处减少了 20%,但事先处理了大约 50% 的数据。谢谢你的提示。

标签: r list apply dplyr


【解决方案1】:

使用lapply 尝试这些替代方案之一:

large_df$new_c <- Reduce(`|`, lapply(large_df[, 2:3], `%in%`, long_list))

sapply

large_df$new_c <- rowSums(sapply(large_df[, 2:3], `%in%`, long_list)) > 0

两者都返回:

large_df
#  A B C new_c
#1 1 a e  TRUE
#2 2 b f  TRUE
#3 3 c g  TRUE
#4 4 d h FALSE

【讨论】:

  • 谢谢罗纳克。在 knytt 建议使用 data.table 和 Reduce() lapply() 的情况下,我的延时时间提高了 12 倍。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-01
  • 2020-05-23
  • 1970-01-01
相关资源
最近更新 更多