【问题标题】:data.table equivalent of complete/fill from tidyrdata.table 相当于 tidyr 的完成/填充
【发布时间】:2017-09-14 17:29:47
【问题描述】:

我有以下数据

library(tidyr)
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(data.table)
#> 
#> Attaching package: 'data.table'
#> The following objects are masked from 'package:dplyr':
#> 
#>     between, first, last

df <- structure(list(filename = c("PS92_019-6_rovT_irrad.tab", "PS92_019-6_rovT_irrad.tab", 
  "PS92_019-6_rovT_irrad.tab", "PS92_019-6_rovT_irrad.tab"), depth = c(5, 
  10, 20, 75), ps = c(3.26223404971255, 3.38947945477306, 3.97380593851983, 
  0.428074807655144)), row.names = c(NA, -4L), class = c("tbl_df", "tbl", 
  "data.frame"), .Names = c("filename", "depth", "ps"))

df
#> # A tibble: 4 x 3
#>                    filename depth        ps
#>                       <chr> <dbl>     <dbl>
#> 1 PS92_019-6_rovT_irrad.tab     5 3.2622340
#> 2 PS92_019-6_rovT_irrad.tab    10 3.3894795
#> 3 PS92_019-6_rovT_irrad.tab    20 3.9738059
#> 4 PS92_019-6_rovT_irrad.tab    75 0.4280748

在此数据中,深度 = 0 处缺少观测值。使用 tidyr, 我可以完成它:

df %>% tidyr::complete(depth = c(0, unique(depth))) %>% fill(everything(), .direction = "up")  ## use the last observations to fill the new line
#> # A tibble: 5 x 3
#>   depth                  filename        ps
#>   <dbl>                     <chr>     <dbl>
#> 1     0 PS92_019-6_rovT_irrad.tab 3.2622340
#> 2     5 PS92_019-6_rovT_irrad.tab 3.2622340
#> 3    10 PS92_019-6_rovT_irrad.tab 3.3894795
#> 4    20 PS92_019-6_rovT_irrad.tab 3.9738059
#> 5    75 PS92_019-6_rovT_irrad.tab 0.4280748

问题是我必须在一个大型数据集上运行它,我发现 完成/填充功能有点慢。因此,我想给 它与 data.table 一起去看看它是否可以加快速度。但是,我 我无法理解它。任何帮助表示赞赏。

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    它没有特定的功能,但您可以通过以下方式实现相同的功能:

    # load package
    library(data.table)
    
    # convert to a 'data.table'
    setDT(df)
    
    # expand and fill the dataset with a rolling join
    df[.(c(0, depth)), on = .(depth), roll = -Inf]
    

    给出:

                        filename depth        ps
    1: PS92_019-6_rovT_irrad.tab     0 3.2622340
    2: PS92_019-6_rovT_irrad.tab     5 3.2622340
    3: PS92_019-6_rovT_irrad.tab    10 3.3894795
    4: PS92_019-6_rovT_irrad.tab    20 3.9738059
    5: PS92_019-6_rovT_irrad.tab    75 0.4280748
    

    向@Frank 提出改进建议。


    旧解决方案:

    df[CJ(depth = c(0,unique(depth))), on = 'depth'
       ][, c(1,3) := lapply(.SD, zoo::na.locf, fromLast = TRUE), .SDcols = c(1,3)][]
    

    【讨论】:

    • 谢谢回答。如何在这种情况下添加group_by?如果我有几个行数不同的filename
    猜你喜欢
    • 2017-09-14
    • 2018-04-16
    • 2017-11-01
    • 1970-01-01
    • 2015-03-19
    • 2019-03-10
    • 2021-10-22
    • 2013-11-03
    相关资源
    最近更新 更多