【问题标题】:how ifelse (in data.table) works [duplicate]ifelse(在data.table中)如何工作[重复]
【发布时间】:2016-05-21 10:27:47
【问题描述】:

在我的data.table 中,如果每个by 组中有多个条目,我想计算条目:

dt1 <- data.table(col1=1:4, col2 = c('A', 'B', 'B', 'C'))
#    col1 col2
# 1:    1    A
# 2:    2    B
# 3:    3    B
# 4:    4    C

dt1[, col3:={
  if (.N>1) {paste0((1:.N), "_", col2)} else {col2};
}, by=col2]

#    col1 col2 col3
# 1:    1    A    A
# 2:    2    B  1_B
# 3:    3    B  2_B
# 4:    4    C    C

这很好用,但是当我尝试改用 ifelse() 时却没有用:

dt1[, col4:=ifelse (.N>1, paste0((1:.N), "_", col2), col2), by=col2]
#    col1 col2 col3 col4
# 1:    1    A    A    A
# 2:    2    B  1_B  1_B
# 3:    3    B  2_B  1_B
# 4:    4    C    C    C

谁能解释一下原因?

【问题讨论】:

  • ifelse 为每个测试返回一个值。你想要不止一个。它只返回1_B,因为它是内置的。
  • @PierreLafortune,谢谢,这似乎确实是该问题的副本。我只是期望“一个值”也可以是一个向量值。目前的行为对我来说看起来相当不直观,但没关系

标签: r data.table


【解决方案1】:

这仅通过与data.table相关的代理;核心是 ifelse 设计用于:

ifelse(test, yes, no)

where testyesno 都具有相同的长度 -- 输出将与 test 的长度相同,并且所有与 where @ 对应的元素987654329@ 是TRUE 将是来自yes 的对应元素,同样testFALSE

test 是标量而yesno 是向量时,就像您的情况一样,您必须查看ifelse 正在做什么才能了解​​发生了什么:

相关来源:

if (any(test[ok])) #is any element of `test` `TRUE`?
        ans[test & ok] <- rep(yes, length.out = length(ans))[test & 
            ok]

rep(c(1, 2), length.out = 1) 是什么?只是1——第二个元素被截断了。

这就是这里发生的事情——ifelse 的值只是paste0(1:.N, "_", col2) 的第一个元素。当传递给`:=` 时,这个单一元素会被回收。

当您的逻辑条件是标量时,您应该使用if,而不是ifelse。我还要补充一点,我尽量避免使用ifelse,因为it's slow

【讨论】:

    猜你喜欢
    • 2018-10-21
    • 2017-10-01
    • 1970-01-01
    • 2018-08-01
    • 2017-03-11
    • 2020-04-20
    • 1970-01-01
    • 1970-01-01
    • 2015-04-17
    相关资源
    最近更新 更多