【问题标题】:Can I do this with data.table without using the merge() function?我可以在不使用 merge() 函数的情况下对 data.table 执行此操作吗?
【发布时间】:2019-05-29 19:47:30
【问题描述】:

我使用非常庞大的数据集,我正在尝试加快我的 R 代码。 这是一个数据示例:

dt <- data.table(id = c(100,101,102,103, 104), sex = c("m","f","m","m","f"), 
value = c(32,14,32,03,03))

data look like this :
    id sex value
1: 100   m    32
2: 101   f    14
3: 102   m    32
4: 103   m     3
5: 104   f     3 

我想要的最终输出:

   value f.value m.value f   m
1:     3    1       1    1   1
2:    14    1       NA   1   NA
3:    32    NA      2    NA  2

我目前使用的代码:

dt_u <- unique(dt, by = c("id", "sex", "value"))
dt_u <- dt_u[, .(n = .N), keyby = .(value, sex)]
dt_u <- dcast(dt_u, value ~ sex, value.var = "n")
dt_t <- dt[, .(n = .N), keyby = .(value, sex)]
dt_t <- dcast(dt_t, value ~ sex, value.var = "n")
dt <- merge(dt_t, dt_u, by = "value", all = TRUE)

代码运行良好,问题是 dt_u 和 dt_t 的合并在 10GB + 数据上可能需要很多时间。所以我的问题是:是否可以在不必“拆分”数据然后合并的情况下获得相同的最终输出?

如果可能的话,我希望答案在 data.table 中, 谢谢。

编辑:示例和解释。 ID代表一个人,这个人可以多次去同一个位置(值)。对于此示例,您可以说每个值代表一个不同的城市。

IE:

dt <- data.table(value = c(21,21,21,21,21,40,1,22,1,1,22, 22, 49, 
49,21,21,1,1,1), id = 
c(1000716624,1000722724,1000716624,1000746824,1001012024,
1002067324,1002743624,1002743645, 1002743636, 
1002743423,1000716624,1000722724, 1000722724,1001012024, 
1000716624,1000716624,1002743624,1002743624,1002743624), sex = c("f", "m", 
"m", "m", "f", "f", "m", "f", "f", "m", "f", "m", "m", "f","f","f", "m", 
"m", "m"))

输出:

 value   places_women   places_men  number_women   number_men
1:     1            1          5            1          2
2:    21            4          3            2          3
3:    22            2          1            2          1
4:    40            1         NA            1         NA
5:    49            1          1            1          1

【问题讨论】:

  • 不确定我是否会随时将 R 与 10GB 的数据一起使用 - 但您能否不只是遍历两列(python 中的 iterrows)并创建项目的地图/字典。在哪里有 {3: {'f': 1, 'm':1}} 之类的东西。你只需要循环一次。然后计算并更新计数器。
  • 几个问题。您的总体目标是计算与每个值关联的mf 的数量(返回NA 以表示不匹配)?这个id 专栏重要吗?是否存在f.valuem.value 不会在您的预期输出中反映fm 的情况。
  • @Chinny84 嗨,我的工作要求我使用 R,所以我必须坚持下去,尽管我同意 R 对于海量数据可能有点反复无常。您的答案似乎可以肯定地起作用,我会尝试一下。谢谢。
  • @Andrew 1. 是的,尽管真实数据集(数百万行)中没有 NA。 2. 是的,id 列很重要,因为 unique(id) 给了我人数。 id 列实际上给了我某人去某个地方的次数(所以我将按性别的人数与他们去过的地方进行比较)。 3. 通常它们应该镜像 f 和 m。谢谢。
  • f.value m.value f m 为什么你有重复的列?

标签: r merge data.table


【解决方案1】:

这适用于第二个示例(基于对所需输出的逆向工程):

> dcast(dt, value ~ sex, value.var=list("value", "id"), fun=list(length, uniqueN), fill=NA)
   value value.1_length_f value.1_length_m id_uniqueN_f id_uniqueN_m
1:     1                1                5            1            2
2:    21                4                3            2            3
3:    22                2                1            2            1
4:    40                1               NA            1           NA
5:    49                1                1            1            1

如果这不适用于完整的问题,更明确地描述每列中应该进行哪些计算(并且可能在示例中更自然的列名称)会有所帮助。

【讨论】:

    【解决方案2】:
    library(data.table)
    
    dt <- data.table(id = c(100,101,102,103, 104), sex = c("m","f","m","m","f"), 
                     value = c(32,14,32,03,03))
    
    dcast(unique(unique(dt, 
                        by = c("id", "sex", "value"))[ , 
    
                count := .N, by = list(value,sex)][,
            id:=NULL]), 
    value ~ sex, value.var = "count")
    
    #>    value  f  m
    #> 1:     3  1  1
    #> 2:    14  1 NA
    #> 3:    32 NA  2
    

    reprex package (v0.3.0) 于 2019 年 5 月 29 日创建

    【讨论】:

    • 感谢您的回答。我如何获得f.valuem.value tho?
    • @Gainz 这些只是fm 列的重复项吗?我还是不知道s.values 有什么区别?
    • 不,抱歉。我应该以不同的方式命名它们。由于该示例仅包含几个值,因此看起来它们是重复的。我会在我的问题中更改名称。
    • @Gainz 让我们把命名问题放在一边。它们的值与您预期输出中的fm 完全相同。你还在用list(value,sex) 数数吗?如果是这样,它们就是重复的。
    • 是的,因为该示例不包含足够的数据。我会尝试添加一个更好的例子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-24
    • 2018-06-16
    • 1970-01-01
    • 1970-01-01
    • 2017-10-27
    相关资源
    最近更新 更多