【问题标题】:Change vector value based on value in same vector根据同一向量中的值更改向量值
【发布时间】:2016-09-23 22:52:53
【问题描述】:

这可能与之前发布的其他问题类似,但我找不到完全匹配的问题(如果它已经在此处,请指导我)。

无论如何,我有一个 19 列和约 5,000 行的矩阵。每行包含一个介于 0.0 和 1 之间的值,增量为 0.1(因此,0.0, 0.1,0.2...1.0),如下所示:

0 0.6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0.5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0.4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
...
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0.9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0.8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

所以向量从 1 变为 0.1,然后从 1 重新开始并转移到下一列。我想要一个基本上从一行到另一行的函数,看看是否有一个数值,然后将 1 减去该值放在向量中的下一个位置。实际上是这样的:

0 0.6 0.4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0.5 0.5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0.4 0.6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
...
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0.9 0.1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0.8 0.2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

我已经尝试了一些“应用”或只是基本重新编码的方法,但诀窍是让它遍历所有约 5,000 行。也许我应该通过列来接近它?

【问题讨论】:

  • 您可以使用ifelse 处理列,检查前一列值并在条件匹配时更改当前列。 ifelse 是矢量化的,因此每列操作都很快。你需要一个 for 循环从最右边的列开始到左边。
  • 另一种方法是计算所有要更改的单元格的索引,放入一个向量中,将所有要更新的值按相同的顺序计算,放入另一个向量中,然后按索引进行更新.

标签: r vector


【解决方案1】:

分别考虑价值和指数。 R 中的索引可能非常强大。

# simulate data. smaller size for simplification
m <- matrix(0, nrow = 200, ncol = 12)
r_indice <- 1:200
c_indice <- rep(2:11, each = 10)
m[cbind(r_indice, c_indice)] <- rep(seq(0.1, 1, by = 0.1), 10)

# find non-zero value indice
value_indice <- which(m !=0, arr.ind = T)
new_value_indice <- value_indice
new_value_indice[, 2] <- new_value_indice[, 2] + 1
m[new_value_indice] <- 1 - m[value_indice]

【讨论】:

  • 谢谢!这非常有效。我没有考虑一次索引整个矩阵。我必须做的唯一更改是在矩阵的末尾添加一个虚拟列,以适应列索引引用中的“+1”移位,否则我会收到“下标越界”错误。我现在可以简单地删除该列,而不会影响矩阵的其余部分。
【解决方案2】:

这是一种结合简单矩阵乘法和矩阵索引的方法。首先,我们创建一个 19 x 20 矩阵,每行包含一对 1 和 -1。

mat <- diag(20)
mat[row(mat) - col(mat) == -1]  <- -1
mat <- mat[-20, ]

mat 看起来像:

#      [,1] [,2] [,3] [,4] [,5] [,6] ...
# [1,]    1   -1    0    0    0    0
# [2,]    0    1   -1    0    0    0
# [3,]    0    0    1   -1    0    0
# [4,]    0    0    0    1   -1    0
# [5,]    0    0    0    0    1   -1
# [6,]    0    0    0    0    0    1
# ...

假设您的原始矩阵是x。然后我们将xmat 相乘:

y <- x %*% mat

这样我们就可以得到与x 相同的数字,但也会得到相邻列中这些数字的负数:

     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    0  0.6 -0.6  0.0    0    0
[2,]    0  0.5 -0.5  0.0    0    0
[3,]    0  0.4 -0.4  0.0    0    0
[4,]    0  0.0  1.0 -1.0    0    0
[5,]    0  0.0  0.9 -0.9    0    0
[6,]    0  0.0  0.8 -0.8    0    0

最后,将所有负数加 1:

y[y < 0] <- (y + 1)[y < 0]
y[1:6, 1:6]
#      [,1] [,2] [,3] [,4] [,5] [,6]
# [1,]    0  0.6  0.4  0.0    0    0
# [2,]    0  0.5  0.5  0.0    0    0
# [3,]    0  0.4  0.6  0.0    0    0
# [4,]    0  0.0  1.0  0.0    0    0
# [5,]    0  0.0  0.9  0.1    0    0
# [6,]    0  0.0  0.8  0.2    0    0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-09
    • 2012-03-13
    • 2019-10-27
    • 1970-01-01
    相关资源
    最近更新 更多