R:将矩阵列数的向量展开为填充了这些列的矩阵

时间:2015-03-14 00:42:02

标签: r matrix vector subset

我在R中有两个向量,并希望根据它们生成一个新矩阵。

a=c(1,2,1,2,3)      # a[1] is 1: thus row 1, column 1 should be equal to...
b=c(10,20,30,40,50) # ...b[1], or 10.

我想制作矩阵' v'但没有我的' for'循环遍历v和我的乘法列:

v = as.data.frame(matrix(0,nrow=length(a),ncol=length(unique(a))))
for(i in 1:ncol(v)) v[[i]][a==i] <- 1   # looping through columns of 'v'
v <- v*b

我确信在R中有一种快速/优雅的方式。至少在扩展&#39; a&#39;进入早期版本的&#39; v&#39; (在乘以&#39; b&#39;之前)。

非常感谢!

2 个答案:

答案 0 :(得分:3)

这是可以定义稀疏矩阵的一种方法。

Matrix::sparseMatrix(i = seq_along(a), j = a, x = b)

答案 1 :(得分:2)

# Setup the problem:
set.seed(4242)
a <- sample(1:100, 1000000, replace = TRUE)
b <- sample(1:500, length(a), replace = TRUE)  
# Start the timer 
start.time <- proc.time()[3]

# Actual code
# We use a matrix instead of a data.frame
# The  number of columns matches the largest column index in vector "a"
v <- matrix(0,nrow=length(a), ncol= max(a))
v[cbind(seq_along(a), a)] <- b

# Show elapsed time
stop.time <- proc.time()[3]
cat("elapsed time is: ", stop.time - start.time, "seconds.\n")

# For a million rows and a hundred columns, my prehistoric
# ... laptop says: elapsed time is:  2.597 seconds.

# these checks take much longer to run than the function itself
# Make sure the modified column in each row matches vector "a"
stopifnot(TRUE == all.equal(a, apply(v!=0, 1, which)))
# Make sure the modified value in each row equals vector "b"
stopifnot(TRUE == all.equal(rowSums(v), b))