替换矩阵中紧跟的特定数字

时间:2019-01-04 23:30:43

标签: r dataframe matrix

我正在使用调查数据,我想替换数据框中彼此跟随的特定值。

例如

   v1   v2   v3   v4  v5
   0    2    0    0   55
   0    0    3    0    1
   3    0    1    1    2
   0    2    0    2    0

如果我将(0,2,0)替换为1,并将其余数据帧替换为0,则新矩阵将如下所示:

   v1   v2   v3   v4  v5
   1    1    1    0    0
   0    0    0    0    0
   0    0    0    0    0
   1    1    1    1    1

我该如何对n个特定长度的数字进行操作,即(1,3); (1,2,4,5,8,2)?

1 个答案:

答案 0 :(得分:0)

正如其他人指出的那样,您需要稍微澄清您的问题,以确保我们能够正确回答。

我的假设是,您在显示的示例中匹配一个模式(c(0,2,0)),并且您仅在各行之间匹配该模式。也就是说,它不能从第2行第5列包装到第3行第1列,也不能仅检查各列中的匹配项。

如果这些假设正确,则以下功能将起作用。它复制您提供的示例,并返回一个矩阵。您可以使用可选参数分别修改示例中的替换值(rep_val和填充值(fill_val)1和0。也可以改进此功能以使其更优雅,但我认为它可以工作。


代码

replace_pattern <- function(x, pattern, rep_with = 1, fill_val = 0)
{
  n <- length(pattern)
  if (n > ncol(x))
    stop("pattern is longer than number of columns")

  new_x <- matrix(fill_val, nrow = nrow(x), ncol = ncol(x))

  # loop over each row
  for (rr in seq_len(nrow(x))) {
    # start matching the pattern at the entry = length of pattern
    # and look backwards
    for (cc in n:ncol(x)) {
      cur_cols <- (cc - n + 1):cc
      cur_vals <- x[rr, cur_cols]

      # if it matches the pattern, replace the values with specified value
      if (isTRUE(all.equal(cur_vals, pattern, check.attributes = FALSE))) {
        new_x[rr, cur_cols] <- rep_with
      }
    }
  }

  new_x
}

测试

使用您的示例,并将其设置为xx

xx

v1   v2   v3   v4  v5
0    2    0    0   55
0    0    3    0    1
3    0    1    1    2
0    2    0    2    0

然后调用replace_pattern(xx, c(0, 2, 0))将返回您提供的第二个矩阵。

x2 <- xx
x2[2, 2] <- 1
replace_pattern(x2, c(1, 3))

返回:

     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    0    0    0
[2,]    0    1    1    0    0
[3,]    0    0    0    0    0
[4,]    0    0    0    0    0

xx3 <- rbind(xx, c(1, 2, 4, 5, 8))
replace_pattern(xx3, c(1, 2, 4, 5, 8))

返回:

     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    0    0    0
[2,]    0    0    0    0    0
[3,]    0    0    0    0    0
[4,]    0    0    0    0    0
[5,]    1    1    1    1    1

最后,replace_pattern(xx, c(1,2,4,5,8,2))将失败,因为该模式比列数长。