不确定这是否有资格获得R-Inferno中的条目,但有人可以评论以下替代方式背后的逻辑吗?
foo<-matrix(1:6,2)
bar<-foo[2,c(1,3,1)]
bar
# [1] 2 6 2
foo[2,c(1,3,1)]<-foo[2,c(1,3,1)]+5
foo
# [,1] [,2] [,3]
# [1,] 1 3 5
# [2,] 7 4 11
我的问题是:生成bar
时,重复的坐标会在输出中产生重复的元素,但在修改foo
时,重复的坐标会不导致重复的加法操作。 (相比之下,for(j in c(1,3,1) ) foo[2,j]<-foo[2,j]+5
确实如此)。为什么&amp; [<-
究竟如何忽略重复索引?
答案 0 :(得分:5)
来自help("[<-")
:
子分配是按顺序完成的,因此如果指定的索引更多 而不是一次索引的最新指定值。
foo<-matrix(1:6,2)
foo[1,rep(1,2)] <- c(1,42)
# [,1] [,2] [,3]
#[1,] 42 3 5
#[2,] 2 4 6
答案 1 :(得分:1)
试图间接回答评论中的次要问题:
> vec <- 1:10
> microbenchmark(
+ rep(1, 1e4),
+ vec[rep(1, 1e4)] <- 1:1e4,
+ vec[1] <- 1e4
+ )
Unit: microseconds
expr min lq median uq max neval
rep(1, 10000) 16.457 17.9190 18.2860 19.0170 2561.327 100
vec[rep(1, 10000)] <- 1:10000 215.395 219.7835 227.8285 233.6795 3437.532 100
vec[1] <- 10000 1.463 2.1950 3.2920 3.8405 22.308 100
强烈建议将相同的值一遍又一遍地分配给相同的内存位置,直到只有最后一个占优势。为什么不添加它们只是因为这里的操作是覆盖,而不是添加(尽管这可能不是你所要求的“不会导致重复的添加操作”)。
请注意,您的循环和直接分配不等同,因为在循环中您正在阅读,添加,分配,重新阅读,重新添加,重新分配等,而在您的直接分配中,您正在阅读一次,将单个向量添加一次,然后仅通过覆盖保留最后一个值。
“读取”之间的关键区别在于,预期的“输出”是索引向量的向量长度,而“写入”的长度(不包括使用越界索引的情况)向量的长度受到你写的矢量的限制。