【问题标题】:Replace values in a vector based on another vector基于另一个向量替换向量中的值
【发布时间】:2011-04-23 17:35:02
【问题描述】:

我想用另一个向量 (y) 中的值替换向量 (x) 中的值。 Catch 22:方法需要是动态的,以适应向量x 中不同数量的“级别”。例如,考虑向量x

x <- sample(c(1, 2, 3, 4, 5), 100, replace = TRUE)
> x
  [1] 2 4 1 1 3 1 1 1 1 1 2 2 5 5 4 5 5 3 4 1 2 2 3 3 3 5 1 3 4 5 5 3 2 4 3 1 3
 [38] 1 4 5 4 1 4 5 4 5 2 4 2 5 3 4 3 1 2 1 1 5 1 4 2 2 5 2 2 4 5 2 4 5 2 5 4 1
 [75] 3 3 4 4 1 1 4 4 2 4 5 4 5 5 4 2 5 2 4 5 3 2 1 1 2 2

我想用 100 替换 1s,用 200 替换 2s 等等。

这可以通过 for 循环轻松完成,但对于大型向量,数十万个值,这是非常低效的。有什么优化代码的技巧吗?

x <- sample(c(1, 2, 3, 4, 5), 100, replace = TRUE)
y <- c(100, 200, 300, 400, 500)
x.lvl <- c(1, 2, 3, 4, 5)
x.temp <- x

for (i in 1:length(y)) {
    x.temp[which(x == x.lvl[i])] <- y[i]
}

【问题讨论】:

    标签: r replace


    【解决方案1】:

    使用因子可能会更快:

    xf <- as.factor(x)
    y[xf]
    

    请注意,levels(xf) 为您提供了一个类似于 x.lvl 的字符向量。因此,要使此方法起作用,y 的元素应对应于levels(xf) 的适当元素。

    【讨论】:

    • 在玩具示例中,您甚至可以使用 y[x]
    • 完美。它甚至可以在不转换为因子的情况下工作,并检测 x 是否具有比 y 预见的更多“级别”。
    • 使用匹配,正如 Marek 建议的那样,这是一种通用的方法,不需要转换为因子。幸运的是,您的 x 向量仅包含从 1 到 N 的数字,因此您可以使用 y[x] 中的位置匹配。
    • 也许我应该明确表示这种方式可以满足我的需求,而其他人可能并非如此。谢谢你的警告。 Marek,您能否修改您的帖子并提及您的方法的一般性?
    【解决方案2】:

    试试match

    y[match(x, x.lvl)]
    

    【讨论】:

    • 你不需要匹配。只需使用 y[x]
    • @Mahbub 在这种情况下是的,但通常您需要匹配(例如,如果 x 是字母向量)。检查 VitoshKa 答案下方的 cmets。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-05
    • 1970-01-01
    • 2017-11-12
    • 2019-09-01
    • 1970-01-01
    相关资源
    最近更新 更多