在我的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
任何人都可以解释原因吗?
答案 0 :(得分:3)
这只是通过与data.table
相关的代理;核心是ifelse
设计用于:
ifelse(test, yes, no)
其中test
,yes
和no
都具有相同的长度 - 输出的长度与test
相同,与test
TRUE
的对应元素对应的所有元素都是yes
的对应元素,test
FALSE
的对应元素也是如此。
当test
是标量而yes
或no
是向量时,就像你的情况一样,你必须看看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。