替换R中向量中多次出现的值

时间:2015-01-28 18:01:19

标签: r vector replace

我有一个值向量

x <- c(1,2,3,4,5)

我希望用向量y中的值替换每次出现:

y <- c(8,9,11,24,56)

这样当我在像

这样的矢量上测试时
z <- (1,2,3,4,5,4,3,4,2,3,2,3,4)

我现在回到z等于

z <- (8,9,11,24,56,24,11,24,9,11,9,11,24)

3 个答案:

答案 0 :(得分:5)

您可以使用功能match查找zx之间的匹配项,并将其用于y的索引编制:

y[match(z,x)]
# [1]  8  9 11 24 56 24 11 24  9 11  9 11 24

答案 1 :(得分:3)

只要您的x向量从1到N计数,Richard Scriven的评论就会起作用。 要获得更通用的解决方案,您需要y引用x

unlist(sapply(z, function(j) y[which(j==x)]))

编辑:时间试验: (但请记住,如果findInterval不是单调的话,x将失败)

x <- 1:100
y <- sample(1:150,100,rep=TRUE)
z <- sample(1:100,300,rep=TRUE)

carl<-function(z,y,x) unlist(sapply(z, function(j) y[which(j==x)]))
marat<-function(z,y,x) y[match(z,x)]
akrun <- function(z,y,x) y[findInterval(z,x)]
microbenchmark(carl(z,y,x),marat(z,y,x),akrun(z,y,x),times=10)
Unit: microseconds
           expr     min      lq      mean  median       uq      max neval
  carl(z, y, x) 966.181 979.116 1088.7465 995.981 1090.096 1661.516    10
 marat(z, y, x)  17.888  18.600   23.9291  19.638   24.879   50.251    10
 akrun(z, y, x)  24.823  25.602   40.2708  26.897   29.375  159.849    10
 cld
   b
  a 
  a

答案 2 :(得分:3)

您还可以使用fmatch

中的library(fastmatch)
library(fastmatch)
y[fmatch(z,x)]
#[1]  8  9 11 24 56 24 11 24  9 11  9 11 24

基准

使用稍大的数据集,

 x <- 1:10000
 set.seed(24)
 y <- sample(1:15000,10000,rep=TRUE)
 z <- sample(1:10000, 30000,rep=TRUE)
 akrun <- function(z,y,x) y[findInterval(z,x)]
 akrun2 <- function(z,y,x) y[fmatch(z,x)]

 carl<-function(z,y,x) unlist(sapply(z, function(j) y[which(j==x)]))
 marat<-function(z,y,x) y[match(z,x)]
 microbenchmark(carl(z,y,x),marat(z,y,x),
       akrun(z,y,x),akrun2(z,y,x), times=10, unit='relative')
 #Unit: relative
 #       expr        min          lq        mean      median          uq
 #  carl(z, y, x) 1997.57314 1997.697643 1902.240056 1857.202479 1894.021674
 # marat(z, y, x)    2.51456    2.491950    2.359782    2.070617    2.522286
 # akrun(z, y, x)    4.66293    4.497809    5.047581    4.782319    5.717679
 #akrun2(z, y, x)    1.00000    1.000000    1.000000    1.000000    1.000000
  #        max neval cld
  # 1985.451747    10  b
  #    2.497346    10  a 
  #    5.723705    10  a 
  #    1.000000    10  a