【问题标题】:How to do use `replace` properly in complex cases?在复杂情况下如何正确使用`replace`?
【发布时间】:2019-03-25 23:02:36
【问题描述】:

我了解了可以成为我朋友的replace 函数

dat1 <- data.frame(matrix(1:12, 3, 4))
rpl <- c(2, 4, 1)
t(sapply(seq_along(rpl), function(x) replace(dat1[x, ], rpl[x], NA)))
#      X1 X2 X3 X4
# [1,] 1  NA 7  10
# [2,] 2  5  8  NA
# [3,] NA 6  9  12

但我没有让它在更复杂的替换情况下工作:

(M <- structure(c(3L, 9L, 14L, 16L, 6L, 8L, 10L, 15L, 1L, 4L, 11L, 
                 13L, 2L, 5L, 7L, 12L), .Dim = c(4L, 4L), .Dimnames = list(NULL, 
                                                                           NULL)))
#      [,1] [,2] [,3] [,4]
# [1,]    3    6    1    2
# [2,]    9    8    4    5
# [3,]   14   10   11    7
# [4,]   16   15   13   12

dat2 <- data.frame(x=matrix(NA, 16))

> sapply(1:4, function(j) replace(dat2$x, M[, j], j))
      [,1] [,2] [,3] [,4]
 [1,]   NA   NA    3   NA
 [2,]   NA   NA   NA    4
 [3,]    1   NA   NA   NA
 [4,]   NA   NA    3   NA
 [5,]   NA   NA   NA    4
 [6,]   NA    2   NA   NA
 [7,]   NA   NA   NA    4
 [8,]   NA    2   NA   NA
 [9,]    1   NA   NA   NA
[10,]   NA    2   NA   NA
[11,]   NA   NA    3   NA
[12,]   NA   NA   NA    4
[13,]   NA   NA    3   NA
[14,]    1   NA   NA   NA
[15,]   NA    2   NA   NA
[16,]    1   NA   NA   NA

结果分布在矩阵中,而不仅仅是更改列,而 for 循环或 sapply 给了我想要的:

for (j in 1:4) dat2$x[M[, j]] <- j
# or
sapply(1:4, function(j) dat2$x[M[, j]] <<- j)

> dat3
   x
1  3
2  4
3  1
4  3
5  4
6  2
7  4
8  2
9  1
10 2
11 3
12 4
13 3
14 1
15 2
16 1

在这种/如此复杂的情况下如何正确使用replace

顺便说一句,为什么&lt;&lt;- 的名声如此糟糕,即使它实现了它的目的,至少在这种情况下是这样? (或者这只是一个思维问题,因为我“听到”了一些东西??)。如果它没有被用于意外破坏全局环境中某些东西的函数中,是否有一个非常糟糕的做法的例子?

【问题讨论】:

  • 我无法理解您在第二个示例中尝试执行的操作(例如,rex 来自哪里?)。但是,您可能会研究矩阵索引。在第一个示例中,您可以使用dat1[cbind(seq_len(nrow(dat1)), res)] &lt;- NA&lt;&lt;- 上有一篇与您无关的问题相关的先前帖子。
  • @lmo 这两个小例子应该只是一个代理,当我成功和失败时replace。您介意将我链接到与我无关的&lt;&lt;- 问题的相关帖子吗?
  • 这里有三篇与&lt;&lt;-相关的帖子,其中的答案值得一读。 onetwothree。一个是您发布的链接。

标签: r replace


【解决方案1】:

replace 没有问题。问题是sapply 并行工作(不是并行处理的意义上,而只是概念上的),而不是对前一次迭代的结果应用一次迭代。为此,请使用Reduce

transform(dat2, x = Reduce(function(x, i) replace(x, M[, i], i), init = x, 1:ncol(M)))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-06
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多