【问题标题】:R repeatedly update dataframe with results from for loopR用for循环的结果重复更新数据帧
【发布时间】:2020-06-09 12:54:09
【问题描述】:

我一直在寻找可能的解决方案,并找到了部分适用于我的应用程序的方法。我正在通过循环将丢失的数据添加到“块”中的现有数据框中。更新包含主表中不存在的行。

我遇到的问题是我需要插入第二个表中不存在于第一个表中的行,并在添加新行的地方用 0 填充 Value1 列。

(每个 SubDF 的行数超过 50k 行,每个 MainDF 可以有 50 个 SubDF 进行迭代,从而产生 250 万行 MainDF)

当前代码:(请原谅循环编码,它不起作用。仅用于说明)

Main_DF
df_list <- c(Sub_DF1, Sub_DF2, SubDF3)

for (i in df_list){

Sub_DF <- i

############## Code in question
setDT(Main_DF)
setDT(Sub_DF)

Main_DF[Sub_DF, 
   on=c("Path1", "Path2","File_Name", "ID"),  
   c("value2") := .(i.value2)] 
###############
}

我尝试过的各种其他排列:

#
setDT(Main_DF)
setDT(Sub_DF)
setkeyv(Main_DF, c("Path1", "Path2","File_Name", "ID"))
setkeyv(Sub_DF, c("Path1", "Path2","File_Name", "ID"))
Main_DF<- Main_DF[Sub_DF]

#    
Main_DF<- merge(Main_DF, Sub_DF, by = c("Path1", "Path2","File_Name", "ID"), 
all = TRUE)

#
Main_DF[Sub_DF, on=c("Path1", "Path2","File_Name", "ID"),  
           c("Value2") := .(i.Value2)] 

# 
Main_DF[Sub_DF,]

#    
Main_DF<- Main_DF[Sub_DF, on=c("Path1", "Path2","File_Name", "ID")]

#    
Main_DF[Sub_DF, on=.("Path1", "Path2","File_Name", "ID"),  `:=` (Value2= 
i.Value2)] 

#
Main_DF <- merge(Main_DF,Sub_DF,by=c("Path1", "Path2","File_Name", "ID"),all 
=T, fill.NA = 0)

主DF

Path1   Path2   File_Name   ID   Value1
root    home    Sample1     1    1
root    home    Sample1     2    0
root    home    Sample1     7    1
root    home    Sample2     1    0
root    home    Sample2     2    1
root    home    Sample2     3    1
root    home    Sample2     8    1
root    home    Sample3     1    0
root    home    Sample3     2    1
root    home    Sample3     6    1

Sub DF(循环的第一次迭代)

Path1   Path2   File_Name  ID  Value2
root    home    Sample1    1   5000
root    home    Sample1    2   9000
root    home    Sample1    5   400
root    home    Sample1    6   3500
root    home    Sample1    7   8500
root    home    Sample1    8   2200

Sub DF(循环的第二次迭代)

Path1   Path2   File_Name  ID  Value2
root    home    Sample2    1   5000
root    home    Sample2    2   9000
root    home    Sample2    3   700
root    home    Sample2    5   400
root    home    Sample2    6   3500
root    home    Sample2    7   8500
root    home    Sample2    8   2200

Sub DF(循环的第三次迭代)

Path1   Path2   File_Name  ID  Value2
root    home    Sample3    1   5000
root    home    Sample3    2   9000
root    home    Sample3    5   400
root    home    Sample3    6   3500
root    home    Sample3    7   8500
root    home    Sample3    8   2200

实际更新的主 DF(迭代 3 个子 DF 后)

Path1   Path2   File_Name   ID   Value1   Value2
root    home    Sample1     1    1        5000
root    home    Sample1     2    0        9000
root    home    Sample1     7    1        8500
root    home    Sample2     1    0        5000   
root    home    Sample2     2    1        9000
root    home    Sample2     3    1        700 
root    home    Sample2     8    1        8800
root    home    Sample3     1    0        5000 
root    home    Sample3     2    1        9000
root    home    Sample3     6    1        3500

希望更新主 DF

Path1   Path2   File_Name   ID   Value1   Value2
root    home    Sample1     1    1        5000
root    home    Sample1     2    0        9000
root    home    Sample1     5    1        400
root    home    Sample1     6    1        3500
root    home    Sample1     7    0        8500
root    home    Sample1     8    0        2200
root    home    Sample2     1    0        5000
root    home    Sample2     2    1        9000
root    home    Sample2     3    1        700
root    home    Sample2     5    0        400
root    home    Sample2     6    0        3500
root    home    Sample2     7    0        8500
root    home    Sample2     8    1        2200
root    home    Sample3     1    0        5000
root    home    Sample3     2    1        9000
root    home    Sample3     5    0        400
root    home    Sample3     6    1        3500
root    home    Sample3     7    0        8500
root    home    Sample3     8    0        2200 

【问题讨论】:

  • @chinsoon12 这是第一次!我需要通过添加一个额外的列和当前不存在的行来更新一个表,然后使用与第一个相同格式的连续表继续更新该表。
  • @chinsoon12 在我的标题为“当前代码”的块中,有一个部分被标记为“有问题的代码”。该代码正在对表执行左连接,但我需要完全连接才能从右表添加左侧不存在的行。

标签: r merge data.table


【解决方案1】:

如果我没记错的话,这应该是你要找的:

rbindlist(list(Sub_DF1, Sub_DF2, Sub_DF3))[
    Main_DF, on=.(Path1, Path2, File_Name, ID), Value1 := i.Value1][
        is.na(Value1), Value1 := 0L][]

输出:

    Path1 Path2 File_Name ID Value2 Value1
 1:  root  home   Sample1  1   5000      1
 2:  root  home   Sample1  2   9000      0
 3:  root  home   Sample1  5    400      0
 4:  root  home   Sample1  6   3500      0
 5:  root  home   Sample1  7   8500      1
 6:  root  home   Sample1  8   2200      0
 7:  root  home   Sample2  1   5000      0
 8:  root  home   Sample2  2   9000      1
 9:  root  home   Sample2  3    700      1
10:  root  home   Sample2  5    400      0
11:  root  home   Sample2  6   3500      0
12:  root  home   Sample2  7   8500      0
13:  root  home   Sample2  8   2200      1
14:  root  home   Sample3  1   5000      0
15:  root  home   Sample3  2   9000      1
16:  root  home   Sample3  5    400      0
17:  root  home   Sample3  6   3500      1
18:  root  home   Sample3  7   8500      0
19:  root  home   Sample3  8   2200      0

数据:

library(data.table)
Main_DF <- fread("Path1   Path2   File_Name   ID   Value1
root    home    Sample1     1    1
root    home    Sample1     2    0
root    home    Sample1     7    1
root    home    Sample2     1    0
root    home    Sample2     2    1
root    home    Sample2     3    1
root    home    Sample2     8    1
root    home    Sample3     1    0
root    home    Sample3     2    1
root    home    Sample3     6    1")

Sub_DF1 <- fread("Path1   Path2   File_Name  ID  Value2
root    home    Sample1    1   5000
root    home    Sample1    2   9000
root    home    Sample1    5   400
root    home    Sample1    6   3500
root    home    Sample1    7   8500
root    home    Sample1    8   2200")

Sub_DF2 <- fread("Path1   Path2   File_Name  ID  Value2
root    home    Sample2    1   5000
root    home    Sample2    2   9000
root    home    Sample2    3   700
root    home    Sample2    5   400
root    home    Sample2    6   3500
root    home    Sample2    7   8500
root    home    Sample2    8   2200")

Sub_DF3 <- fread("Path1   Path2   File_Name  ID  Value2
root    home    Sample3    1   5000
root    home    Sample3    2   9000
root    home    Sample3    5   400
root    home    Sample3    6   3500
root    home    Sample3    7   8500
root    home    Sample3    8   2200")

【讨论】:

  • 问题是 subdf 是在循环中生成的,所以它们一次只存在一个。如果我存储所有这些,然后执行 rbind,我将尝试 rbind 50 个数据帧,每个数据帧 50,000 行。 (这可能是我最终必须要做的,但我认为我做过类似的事情,而且速度很慢。)
  • 我认为如果你一次绑定一个表,它应该会更慢,因为每次分配内存都需要时间。
  • 您是说要使用 rbind,但是在循环中使用一个列表? (而不是您现在拥有的三个 df?)
  • 您可以在使用上面的代码之前分配 data.tables 列表的结果,例如l &lt;- lapply(1:3, function(n) your_code_returning_data.table) 然后rbindlist(l)
【解决方案2】:

所以这不是我正在寻找的实现,但@chinsoon12 解决方案以不同的方式工作。

在处理 SubDF 的循环中,我将 rbind 分配给一个新的数据帧。然后,我在循环回收之前将该较小的数据帧推送到我的数据库,用下一个 SubDF 数据覆盖数据帧。

如果我无法让 data.table join 以我希望的方式工作,这是我计划考虑的途径之一。

感谢您的帮助!

【讨论】:

    猜你喜欢
    • 2017-10-23
    • 2013-05-05
    • 1970-01-01
    • 1970-01-01
    • 2017-11-03
    • 1970-01-01
    • 2013-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多