首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >查找和替换而不回溯

查找和替换而不回溯
EN

Stack Overflow用户
提问于 2014-12-06 23:04:44
回答 1查看 61关注 0票数 1

这里的新手可能是个愚蠢的/简单的问题。

我试图使用R在向量"census.new“中查找和替换(基本上是使用R来完成excel使用查找/替换所做的事情)。但是,由于原始数据(我正在搜索的数据)与我试图替换的数据部分重叠,我最终得到了一些奇怪的结果。

我试着用2008 b替换2,用2009 a替换3,等等。

代码语言:javascript
复制
census.new<-sub("2","2008b", census.new, fixed=TRUE)
census.new<-sub("3","2009a", census.new, fixed=TRUE)
census.new<-sub("4","2009b", census.new, fixed=TRUE)
census.new<-sub("5","2010a", census.new, fixed=TRUE)
census.new<-sub("8","2011b", census.new, fixed=TRUE)
census.new<-sub("10","2012a", census.new, fixed=TRUE)
census.new<-sub("11","2012b", census.new, fixed=TRUE)
census.new<-sub("12","2013a", census.new, fixed=TRUE)
census.new<-sub("13","2013b", census.new, fixed=TRUE)
table(census.new)

得出的表格是:

代码语言:javascript
复制
2002020202013babbb    2009a     2009b     202013ba00202012bbb    202013ba009a
              6268     3129      3129                    3129            3129

20202013baa         20202013bab      2020202013baaa   2020202013babb
       3129                3129                3129             3129 

提前感谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-12-06 23:55:59

您选择使用sub是因为它使用正则表达式:例如,它将"2“的每个实例替换为"2008b",因此"2012”变成"2008b012008b“。由于您随后寻找其他(类似)字符串,它级联(雪球)很快。例如:

代码语言:javascript
复制
gsub('2', '2008b', c('2', '22'), fixed = TRUE)
## [1] "2008b"      "2008b2008b"

有几种方法可以绕过它,有些比其他的更优雅。首先,我将生成一些独特的数据,因为我不知道您的数据是什么样子的:

代码语言:javascript
复制
set.seed(42)
dat <- sample(as.character(c(2, 3, 4, 5, 8, 10, 11, 12, 13)),
              size = 31300, replace = TRUE)
table(dat)
## dat
##    2    3    4    5    8   10   11   12   13 
## 3577 3573 3275 3499 3453 3481 3487 3439 3516 

带正则表达式的sub

到目前为止,这并不是最好或最优的解决方案。如果您想/需要继续使用sub (或gsub),您应该阅读正则表达式 (还有更多的网站和教程供regexp使用)。

代码语言:javascript
复制
dat1 <- sub('^2$', '2008b', dat)
dat1 <- sub('^3$', '2009a', dat1)
dat1 <- sub('^4$', '2009b', dat1)
dat1 <- sub('^5$', '2010a', dat1)
dat1 <- sub('^8$', '2011b', dat1)
dat1 <- sub('^10$', '2012a', dat1)
dat1 <- sub('^11$', '2012b', dat1)
dat1 <- sub('^12$', '2013a', dat1)
dat1 <- sub('^13$', '2013b', dat1)
table(dat1)
## dat1
## 2008b 2009a 2009b 2010a 2010b 2012a 2012b 2013a 2013b 
##  3577  3573  3275  3499  3453  3481  3487  3439  3516 

您可以嵌套这些(sub('^2$', '2008b', sub('^3$', '2009a', dat))),但它并不能使其更易读或更可扩展。它也很丑(IMHO)。

汽车::recode

这个函数是为了(我推断的是)你的目的。

代码语言:javascript
复制
library(car)
dat2 <- recode(dat, "
    2 = '2008b'; 3 = '2009a'; 4 = '2009b';
    5 = '2010a'; 8 = '2011b'; 10 = '2012a';
    11 = '2012b'; 12 = '2013a'; 13 = '2013b'")
table(dat2)
## dat2
## 2008b 2009a 2009b 2010a 2011b 2012a 2012b 2013a 2013b 
##  3577  3573  3275  3499  3453  3481  3487  3439  3516 
identical(dat1, dat2)
## [1] TRUE

相对性能

car::recode的性能也不错:

代码语言:javascript
复制
library(microbenchmark)
microbenchmark(
  re = {
    dat1 <- sub('^2$', '2008b', dat)
    dat1 <- sub('^3$', '2009a', dat1)
    dat1 <- sub('^4$', '2009b', dat1)
    dat1 <- sub('^5$', '2010a', dat1)
    dat1 <- sub('^8$', '2011b', dat1)
    dat1 <- sub('^10$', '2012a', dat1)
    dat1 <- sub('^11$', '2012b', dat1)
    dat1 <- sub('^12$', '2013a', dat1)
    dat1 <- sub('^13$', '2013b', dat1)
  },
  car = {
    recode(dat, "
        2 = '2008b'; 3 = '2009a'; 4 = '2009b';
        5 = '2010a'; 8 = '2011b'; 10 = '2012a';
        11 = '2012b'; 12 = '2013a'; 13 = '2013b'")
  }, times = 50)
## Unit: milliseconds
##  expr      min       lq     mean   median       uq       max neval cld
##    re 74.44709 75.97057 78.10516 77.20569 78.43732 124.42665   100   b
##   car 23.21131 24.11697 26.08724 25.74997 26.25260  77.97541   100  a 
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27337591

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档