【问题标题】:data.table and table unexpected behaviordata.table 和表意外行为
【发布时间】:2013-04-24 20:31:32
【问题描述】:

数据来自我正在玩的另一个问题:

dt <- data.table(user=c(rep(3, 5), rep(4, 5)),
                 country=c(rep(1,4),rep(2,6)),
                 event=1:10, key="user")
#    user country event
#1:     3       1     1
#2:     3       1     2
#3:     3       1     3
#4:     3       1     4
#5:     3       2     5
#6:     4       2     6
#7:     4       2     7
#8:     4       2     8
#9:     4       2     9
#10:    4       2    10

这是令人惊讶的行为:

dt[user == 3, as.data.frame(table(country))]
#  country Freq
#1       1    4
#2       2    1

dt[user == 4, as.data.frame(table(country))]
#  country Freq
#1       2    5

dt[, as.data.frame(table(country)), by = user]
#   user country Freq
#1:    3       1    4
#2:    3       2    1
#3:    4       1    5
#             ^^^ - why is this 1 instead of 2?!

感谢 mnel 和 Victor K。自然的后续是 - 不应该是 2,即这是一个错误吗?我期待

dt[, blah, by = user]

返回相同的结果

rbind(dt[user == 3, blah], dt[user == 4, blah])

这个预期不正确吗?

【问题讨论】:

  • as.data.frame(table(country)) 中的国家是一个因素吗?如果是这样,那是因为两者的级别不同。
  • @mnel,虽然您是对的,因为 as.data.frame 将强制转换为 factor,但预期的行为将是表示标签的值。我认为这可能与rbindlist 的情况相同:stackoverflow.com/questions/15933846/…
  • @eddi,请参阅我的答案的更新。
  • @eddi -- 我认为在使用j 时天真地使用j 中的因子的问题可能值得一提常见问题解答- 这不是错误。它被记录在案(参见 FAQ 2.3,但它确实需要更多解释0——它也与许多情况下对因子的天真使用一致。
  • @mnel 所以你说我应该期望上面的rbindby 为任何blah 返回相同的结果,而应该期望他们的平等是blah-dependent?

标签: r data.table


【解决方案1】:

惯用的 data.table 方法是使用 .N

 dt[ , .N, by = list(user, country)]

这会快得多,并且还会保留与原始类别相同的国家/地区。

【讨论】:

    【解决方案2】:

    正如 cmets 中的 mnel 所述,as.data.frame(table(...)) 会生成一个数据框,其中第一个变量是一个因子。对于user == 4,因子中只有一级,内部存储为1。

    你想要的是因子levels,但你得到的是因子是如何在内部存储的(作为整数,从 1 开始)。以下提供了预期的结果:

    > dt[, lapply(as.data.frame(table(country)), as.character), by = user]
       user country Freq
    1:    3       1    4
    2:    3       2    1
    3:    4       2    5
    

    更新。关于你的第二个问题:不,我认为data.table 的行为是正确的。当您将两个具有不同级别的因素连接起来时,在普通 R 中也会发生同样的事情:

    > a <- factor(3:5)
    > b <- factor(6:8)
    > a
    [1] 3 4 5
    Levels: 3 4 5
    > b
    [1] 6 7 8
    Levels: 6 7 8
    > c(a,b)
    [1] 1 2 3 1 2 3
    

    【讨论】:

    • 作为感兴趣的注释dt[, lapply(as.data.frame.table(country), as.character), by = user] 给出一个错误。
    • 但这可能与data.table无关:例如as.data.frame.table(dt$country) 产生同样的错误。
    • @VictorK。好吧,那你觉得rbind 做错了吗?
    猜你喜欢
    • 2021-11-16
    • 2013-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多