两个大型数据框的笛卡尔积,保持满足条件的值

问题描述 投票:1回答:1

所以我的问题可能是天真的,但我一直在寻找,我仍然找不到答案。我有两个大数据集:

  1. 一个是人口普查文件,记录超过700,000条。 Lastname Census 1stname Census census_year C2last C2first 1880 C3last C3first 1850 C4last C4first 1850
  2. 另一个是由80,000个观察组成的民事登记样本。 Lastname Reg 1stname reg birth_year P2Last P2first 1818 P3last P3first 1879 P4last P4first 1903

我需要执行两个数据集的笛卡尔积,这显然是一个巨大的文件(700,000 x 80,000),对于人口普查的每一行,我们应该添加80,000个民用寄存器和一个额外的变量。

此额外变量的值满足条件。条件是人口普查年(人口普查的变量)大于民事登记册的变量“出生年份”(换句话说,人口普查年份比登记册上的出生年龄小)。

正如我所说,目标是制作笛卡尔积,但增加一个额外的变量(旗帜),当条件满足时(人口普查年份>出生年份)给出'1'或'0',当它不是:

LastNCens  1stNCens   cens_year  LastNamReg   1stNamReg       birth      Flag
C2last     C2first         1880      P2Last     P2first        1818         1
                                     P3last     P3first        1879         1
                                     P4last     P4first        1903         0
C3last     C3first         1850      P2Last     P2first        1818         1
                                     P3last     P3first        1879         0
                                     P4last     P4first        1903         0
C4last     C4first         1860      P2Last     P2first        1818         1
                                     P3last     P3first        1879         0
                                     P4last     P4first        1903         0

所有这一切,请记住产品太大了。

我尝试过很多东西(比较,差异,交叉),我也读过其他我不能应用的东西(df.wherepd.merge),但它们没有做我需要的东西,我不能在这里使用它们。我的简单方法是:

cp <-  merge(census, register,by=NULL);

final.dataframe <- cp [which (cp$census_year > cp$birth_year_hsn ),]

但是R耗尽内存。

毫无疑问,结果数据框(笛卡尔积)也只对那些标记为'1'的记录有效(摆脱那些带有Flag='0'的记录)。

我希望这个解释得很好,对其他人也很有用......万分感谢任何提示。非常欢迎。

r merge cartesian-product
1个回答
1
投票

随着对问题的评论,你可以使用data.table包来实现你想要的东西。该包通过引用进行修改,因此可以帮助减少用于子集,合并和计算的内存量。有关该软件包的更多信息,我建议使用他们的wikipedia github page,其中包含大多数计算的快速备忘单。

下面是一个如何使用data.table执行您正在寻找的合并类型的示例。它被称为non-equi join。几点说明。似乎data.table包中存在一个错误,尚未被注意到。当您输出两个连接列时,by = .EACHI似乎是必要的,以便获得连接左侧部分的原始值。然而,这是一个很小的成本。

df1 <- fread("Lastname_Census     firstname_Census     census_year                
              C2last                C2first            1880
              C3last                C3first            1850
              C4last                C4first            1850", key = "census_year")
df2 <- fread("Lastname_Reg      firstname_reg       birth_year               
              P2Last              P2first         1818
              P3last              P3first         1879
              P4last              P4first         1903", key = "birth_year")

cart_join <- 
    df2[df1, #join df1 on df2
      on = .(birth_year >= census_year), #join criteria
      #Force keep all columns to keep (i.var, indicates to keep var from df1)
      j = .(i.Lastname_Census,
            i.firstname_Census, 
            Lastname_Reg, 
            firstname_reg, 
            birth_year, 
            i.census_year, 
            Flag = birth_year >= i.census_year), 
      #Force evaluation on each i. This will keep the correct birth_year (seems to be a bug)
      by = .EACHI,
      #Let the table grow beyond nrow(df1) + nrow(df2) 
      allow.cartesian = TRUE][,-1] #Remove the first column. It is a merge column

编辑(一些可能的错误)

在玩了这个连接之后,我注意到了一些违规行为,然后开了一个问题here。请注意,您应该小心我的上述建议的答案。从两个表中返回值(除了在on语句中使用过的值)之外,它似乎工作正常,但它并不是难以理解的。有关更多信息,请参阅我的open issue

© www.soinside.com 2019 - 2024. All rights reserved.