在大型数据表中替换 NA 的最快方法

2024-01-08

我有一个大数据表 http://cran.r-project.org/web/packages/data.table/index.html,许多缺失值分散在大约 20 万行和 200 列中。我想尽可能有效地将这些 NA 值重新编码为零。

我看到两个选择:
1:转换为data.frame,并使用一些东西像这样 http://r.789695.n4.nabble.com/How-to-replace-all-lt-NA-gt-values-in-a-data-frame-with-another-not-0-value-td2125458.html
2:某种很酷的data.table子设置命令

我会对类型 1 的相当有效的解决方案感到满意。转换为 data.frame 然后再转换回 data.table 不会花费太长时间。


这是一个使用的解决方案数据表 http://r-datatable.com's :=运营商,以 Andrie 和 Ramnath 的答案为基础。

require(data.table)  # v1.6.6
require(gdata)       # v2.8.2

set.seed(1)
dt1 = create_dt(2e5, 200, 0.1)
dim(dt1)
[1] 200000    200    # more columns than Ramnath's answer which had 5 not 200

f_andrie = function(dt) remove_na(dt)

f_gdata = function(dt, un = 0) gdata::NAToUnknown(dt, un)

f_dowle = function(dt) {     # see EDIT later for more elegant solution
  na.replace = function(v,value=0) { v[is.na(v)] = value; v }
  for (i in names(dt))
    eval(parse(text=paste("dt[,",i,":=na.replace(",i,")]")))
}

system.time(a_gdata = f_gdata(dt1)) 
   user  system elapsed 
 18.805  12.301 134.985 

system.time(a_andrie = f_andrie(dt1))
Error: cannot allocate vector of size 305.2 Mb
Timing stopped at: 14.541 7.764 68.285 

system.time(f_dowle(dt1))
  user  system elapsed 
 7.452   4.144  19.590     # EDIT has faster than this

identical(a_gdata, dt1)   
[1] TRUE

请注意,f_dowle 通过引用更新了 dt1。如果需要本地副本,则显式调用copy需要函数来制作整个数据集的本地副本。数据表的setkey, key<- and :=不要写时复制。

接下来,让我们看看 f_dowle 都把时间花在哪里了。

Rprof()
f_dowle(dt1)
Rprof(NULL)
summaryRprof()
$by.self
                  self.time self.pct total.time total.pct
"na.replace"           5.10    49.71       6.62     64.52
"[.data.table"         2.48    24.17       9.86     96.10
"is.na"                1.52    14.81       1.52     14.81
"gc"                   0.22     2.14       0.22      2.14
"unique"               0.14     1.36       0.16      1.56
... snip ...

在那里,我会重点关注na.replace and is.na,其中有一些矢量副本和矢量扫描。通过编写一个小的 na.replace C 函数来更新,可以很容易地消除这些问题NA通过向量中的引用。我认为这至少可以将 20 秒时间缩短一半。 R包中是否存在这样的函数?

原因f_andrie失败可能是因为它复制了整个dt1,或者创建一个与整个dt1,几次。其他 2 种方法一次只适用于一列(尽管我只是简单地了解了NAToUnknown).

EDIT(拉姆纳特在评论中要求的更优雅的解决方案):

f_dowle2 = function(DT) {
  for (i in names(DT))
    DT[is.na(get(i)), (i):=0]
}

system.time(f_dowle2(dt1))
  user  system elapsed 
 6.468   0.760   7.250   # faster, too

identical(a_gdata, dt1)   
[1] TRUE

我希望我一开始就这样做!

EDIT2(一年多后,现在)

还有set()。如果有很多列被循环,这会更快,因为它避免了调用的(小)开销[,:=,]循环中。set是一个可循环的:=. See ?set.

f_dowle3 = function(DT) {
  # either of the following for loops

  # by name :
  for (j in names(DT))
    set(DT,which(is.na(DT[[j]])),j,0)

  # or by number (slightly faster than by name) :
  for (j in seq_len(ncol(DT)))
    set(DT,which(is.na(DT[[j]])),j,0)
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在大型数据表中替换 NA 的最快方法 的相关文章

  • 在 R 中,为什么 sum 与其他方法(例如 cumsum)相比如此慢?

    我正在尝试实现一个需要非常快的函数 主要是因为它一遍又一遍地处理巨大的数据帧 R 总是让我感到困惑 为什么它有时有点慢 而有时又慢得离谱 不幸的是 它从来都不快 不管怎样 我一直认为 如果可能的话 当以某种方式推入 apply sapply
  • geom_polygon 的渐变填充

    此代码生成一个包含 3 个多边形的图表 我正在创建一个显示 3 个多边形的图表 如果有更好的方法来绘制多边形 我不太感兴趣 实际上这些多边形代表事件 并且这些事件有一个持续时间 首先 我感兴趣的是使用渐变填充每个多边形的可能性 librar
  • 如何在 R 中解析堆叠多个 JSON 的文件?

    我在 R 中有以下 堆叠 JSON 对象 example1 json ID 12345 Timestamp 20140101 Usefulness Yes Code event1 A result 1 ID 1A35B Timestamp
  • 如何在 R 中“推断”面板数据的值?

    我有一个带有 NA 值的面板数据 如下所示 uid year month day value 1 1 2016 8 1 NA 2 1 2016 8 2 NA 3 1 2016 8 3 30 4 1 2016 8 4 NA 5 1 2016
  • R:中断 for 循环

    你能确认下一个break是否取消了内部for循环吗 for out in 1 n old id velho lt old table df id out for in in 1 n id novo lt new table df ID in
  • R 中的 ddply:对于每个组,查找特定变量的出现百分比

    我有一个数据集 其中包含两列 user type 和滞后响应时间 以天为单位 user type imp date lag Consumer 20130613 1 Consumer 20130612 2 Consumer 20130611
  • 将函数应用于矩阵列表

    我有一个矩阵列表 注意 它们的维度与此示例不同 x lt matrix 1 10 ncol 2 y lt x 300 mylist lt list x y 我想运行一个函数networklevel在矩阵列表中的每个矩阵上 该函数有各种可以计
  • 如何从R中串扰的filter_select中删除(全部)?

    我遵循图 16 7 的示例https plotly r com client side linking html https plotly r com client side linking html并且无法弄清楚为什么有一个名为 全部 的
  • r:按多列分组并计数

    我有以下数据框 df LeftOrRight SpeedCategory NumThruLanes R 25to45 3 L 45to62 2 R Gt62 1 我想按速度类别对其进行分组 并循环遍历其他列以获取每个速度类别中每个唯一代码的
  • AtomicInteger 实现和代码重复

    警告 问题有点长 但分隔线以下的部分仅供好奇 Oracle 的 JDK 7 实现原子整数 http docs oracle com javase 7 docs api java util concurrent atomic AtomicIn
  • R 带有列和行的分面 qqplots

    我需要使用按行和列的构面创建 qqplot 我了解如何用列和行绘制分面图 但我不确定如何设置我的数据 最终 我想按列和行对数据集进行分组 然后按升序对 建模 结果和 观察到 结果进行排序 同时添加带有 行 组的列和带有 列 组的列 我一直在
  • 从受密码保护的站点读取信息

    我一直在 R 教程中使用 readLines 从网站上抓取信息 我现在希望从我自己的网站提取数据 特别是 awstats 数据 但是该域受密码保护 有没有一种方法可以通过用户名和密码传递我需要的特定 awstats 数据的 url url
  • ggsubplot 是否适用于 R 3.2.1+?

    CRAN 提供的 ggsubplot 版本与 R 的最新版本 例如 3 1 1 不兼容 运行 ggsubplot 示例会返回以下错误 Error in layout base data vars drop drop At least one
  • data.table 的包装函数

    我有一个已经使用 data frame 上下文编写的项目 为了缩短计算时间 我尝试利用 data table 的速度 我的方法是构造包装函数 读取帧 将它们转换为表 进行计算 然后转换回帧 这是一个简单的例子 FastAgg lt func
  • 使用 roxygen2 导入两个同名函数

    我是 CRAN 包的维护者 在加载时收到以下消息 checking whether package qdap can be installed 10s 10s WARNING Found the following significant
  • 如何在 R Markdown 中的内联 LateX 方程中输出 R 变量的值(即动态更新)

    我无法找到一种方法将 r 代码实现到 R markdown 中的内联 LateX 方程中 目标是如果变量 值 发生变化 则不必对它们的值进行硬编码 Given values lt c 1 4 2 5 7 9 avg lt sum value
  • 用 OpenCL C 编写快速线性系统求解器

    我正在编写一个 OpenCL 内核 它将涉及求解线性系统 目前我的内核太慢了 提高线性系统部分的性能似乎是一个不错的起点 我还应该注意 我并没有尝试使我的线性求解器并行 我正在研究的问题在宏观层面上已经是令人尴尬的并行 以下是我编写的 C
  • 行方向变异的有效方法

    我有两个数据框 dfUsers and purchases使用以下代码生成 set seed 1 library data table dfUsers lt data table user letters 1 5 startDate sam
  • 在 Python 中伪造一个对象是否是类的实例

    假设我有一堂课FakePerson它模仿基类的所有属性和功能RealPerson 不扩展它 在Python 3中 是否可以伪造isinstance 为了认识到FakePerson as a RealPerson只通过修改对象FakePers
  • 如何通过组度量的平均值在 df 内排列 dplyr:: 组?

    借鉴吴卡拉的设计https stackoverflow com a 26555424 9350837 https stackoverflow com a 26555424 9350837答案 我希望根据各个组汇总测量的平均值对分组 df 进

随机推荐