ifelse(在data.table中)如何工作

时间:2016-02-10 21:06:35

标签: r data.table

在我的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

任何人都可以解释原因吗?

1 个答案:

答案 0 :(得分:3)

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

ifelse(test, yes, no)

其中testyesno具有相同的长度 - 输出的长度与test相同,与test TRUE的对应元素对应的所有元素都是yes的对应元素,test FALSE的对应元素也是如此。

test是标量而yesno是向量时,就像你的情况一样,你必须看看ifelse正在做些什么来理解什么&#39 ; s继续:

相关来源:

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