【问题标题】:r - read in multiple files and select max value from column by groupr - 读入多个文件并按组从列中选择最大值
【发布时间】:2021-05-02 20:01:18
【问题描述】:

我正在寻找最优雅的方式循环并读取按日期组织的多个文件,如果基于多个键发生任何更改,则选择最新的值。

遗憾的是,我需要读取所有文件而不仅仅是最后一个文件的原因是因为文件中可能有一个我想捕获的实例消失了。

以下是文件外观的示例(我发布逗号分隔,即使它是固定宽度)

file_20200101.txt
key_1,key_2,value,date_as_numb
123,abc,100,20200101
456,def,200,20200101
789,xyz,100,20200101
100,foo,15,20200101

file_20200102.txt
key_1,key_2,value,date_as_numb
123,abc,50,20200102
456,def,500,20200102
789,xyz,300,20200102

以及所需输出的示例:

desired_df
key_1,key_2,value,date_as_numb
123,abc,50,20200102
456,def,500,20200102
789,xyz,300,20200102
100,foo,15,20200101

此外,我知道这里有一些代码可以读取多个文件,然后获得理想的输出,但我需要它在循环内。数据框太大而无法导入和绑定所有文件:

files <- list.files(path, pattern = ".txt")

df <- files %>%
  map(function(f) {
    
    print(f)
    
    df <- fread(f)
    df <- df %>% mutate(date_as_numb = f)
    
    return(df)
    
  }) %>% bind_rows()

df <- df %>% 
  mutate(file_date = as.numeric(str_remove_all(date_as_numb, ".*_"))) %>% 
  group_by(key_1, key_2) %>% 
  filter(date_as_numb == max(date_as_numb))

提前致谢!

【问题讨论】:

    标签: r for-loop dplyr


    【解决方案1】:

    不知道什么对你来说“太大了”。数据表可以(据称)处理非常大的数据。所以如果列表的bind_rows不行,可以使用数据表。

    (根据我自己的经验,dplyr::group_by 在大型数据(例如大约 10^6 行)中处理许多组(例如 10^5 组)时可能会非常慢。我对数据没有太多经验。表,但所有线程都提到它对大数据的优越性)。

    我用过this answer for merging a list of data tables

    library(data.table)
    dt1 <- fread(text = "key_1,key_2,value,date_as_numb
    123,abc,100,20200101
    456,def,200,20200101
    789,xyz,100,20200101
    100,foo,15,20200101")
    
    dt2 <- fread(text = "key_1,key_2,value,date_as_numb
    123,abc,50,20200102
    456,def,500,20200102
    789,xyz,300,20200102")
    
    ls_files <- list(dt1, dt2) 
    
    # you would have created this list by calling fread with lapply, like 
    # ls_files <- lapply(files, fread)
    
    # Now here a two-liner with data table.
    
    alldata <- Reduce(function(...) merge(..., all = TRUE), ls_files)
    
    alldata[alldata[, .I[which.max(date_as_numb)], by = .(key_1, key_2)]$V1]
    #>    key_1 key_2 value date_as_numb
    #> 1:   100   foo    15     20200101
    #> 2:   123   abc    50     20200102
    #> 3:   456   def   500     20200102
    #> 4:   789   xyz   300     20200102
    

    reprex package (v0.3.0) 于 2021-01-28 创建

    【讨论】:

    • 我明白你关于大数据的观点,但 R 是一种记忆猪。我有过几次经历,它终止时并没有真正的“那么多数据”。像我的例子一样阅读它,我大约有 270 万行,有 5 个文件,还有大约 1020 个文件要处理。不过我肯定会尝试这个解决方案!
    • 内存效率低下的原因之一是不断增长的对象问题 [R inferno circle 2])burns-stat.com/pages/Tutor/R_inferno.pdf - 所以如果你使用循环,请避免!
    • 这似乎真的很有趣,但遗憾的是,我将不得不列出一长串关于 r 的内容:( 我经常使用map,它确实将数据放入列表中我在过去一年左右开始更多地使用列表,但我已经很清楚如何处理我的问题中的信息与列表。
    • 昨晚我想到的一件事是循环遍历文件并将它们写出,然后在下一次迭代中再次读入文件。所以它就像if 1st file &gt; read in txt &gt; write out csv &gt; next read in csv AND read in new txt &gt; get most up to date instance &gt; write out csv
    猜你喜欢
    • 2012-08-17
    • 2020-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-28
    相关资源
    最近更新 更多