【问题标题】:Renaming duplicate strings in R在R中重命名重复的字符串
【发布时间】:2013-05-14 19:54:42
【问题描述】:

我有一个包含两列字符串的 R 数据框。在其中一列(例如 Column1)中存在重复值。我需要重新标记该列,以便使用有序后缀重命名重复的字符串,例如 Column1.new

 Column1   Column2   Column1.new
 1         A         1_1
 1         B         1_2
 2         C         2_1
 2         D         2_2
 3         E         3
 4         F         4

任何关于如何做到这一点的想法将不胜感激。

干杯,

防盗

【问题讨论】:

    标签: r duplicates rename


    【解决方案1】:

    @Cão 只回答基数 R:

    x=read.table(text="
    Column1   Column2   #Column1.new
    1         A         #1_1
    1         B         #1_2
    2         C         #2_1
    2         D         #2_2
    3         E         #3
    4         F         #4", stringsAsFactors=F, header=T)
    
    string<-x$Column1
    mstring <- make.unique(as.character(string) )
    mstring<-sub("(.*)(\\.)([0-9]+)","\\1_\\3",mstring)
    y <- rle(string)
    tmp <- !duplicated(string) & (string %in% y$values[y$lengths>1])
    mstring[tmp]<-gsub("(.*)","\\1_0", mstring[tmp]) 
    end <- sub(".*_([0-9]+)","\\1",grep("_([0-9]*)$",mstring,value=T) ) 
    beg <- sub("(.*_)[0-9]+","\\1",grep("_([0-9]*)$",mstring,value=T) ) 
    newend <- as.numeric(end)+1
    mstring[grep("_([0-9]*)$",mstring)]<-paste0(beg,newend)
    x$Column1New<-mstring
    x
    

    【讨论】:

      【解决方案2】:

      可能更多的是一种解决方法,但对于那些需求不完全相同的人来说,其中的一部分可能更有用和更简单。 make.namesunique=T 属性添加重复的点和数字名称:

      x <- make.names(tab$Column1,unique=T)
      > print(x)
      [1] "X1"   "X1.1" "X2"   "X2.1" "X3"   "X4"   
      

      这对某些人来说可能已经足够了。然后,您可以在此处获取重复元素的第一个条目,而不是未重复的元素,然后在末尾添加 .0

      y <- rle(tab$Column1)
      tmp <- !duplicated(tab$Column1) & (tab$Column1 %in% y$values[y$lengths>1])
      x[tmp] <- str_replace(x[tmp],"$","\\.0")
      > print(x)
      [1] "X1.0" "X1.1" "X2.0" "X2.1" "X3"   "X4"
      

      替换点并删除 X

      x <- str_replace(x,"X","")
      x <- str_replace(x,"\\.","_")
      > print(x)
      [1] "1_0" "1_1" "2_0" "2_1" "3"   "4" 
      

      对你来说可能已经足够了。但是,如果您希望索引从 1 开始,请抓住数字,加一个然后放回原处。

      z <- str_match(x,"_([0-9]*)$")[,2]
      z <- as.character(as.numeric(z)+1)
      x <- str_replace(x,"_([0-9]*)$",paste0("_",z))
      > print(x)
      [1] "1_1" "1_2" "2_1" "2_2" "3"   "4" 
      

      就像我说的,这里有更多的解决方法,但提供了一些选项。

      【讨论】:

        【解决方案3】:
        d <- read.table(text='Column1   Column2  
         1         A 
         1         B 
         2         C 
         2         D 
         3         E 
         4         F', header=TRUE)
        
        transform(d, 
            Column1.new = ifelse(duplicated(Column1) | duplicated(Column1, fromLast=TRUE), 
                                 paste(Column1, ave(Column1, Column1, FUN=seq_along), sep='_'), 
                                 Column1))
        
        #   Column1 Column2 Column1.new
        # 1       1       A         1_1
        # 2       1       B         1_2
        # 3       2       C         2_1
        # 4       2       D         2_2
        # 5       3       E           3
        # 6       4       F           4
        

        【讨论】:

        • 这实际上是更准确的解决方案,因为我不想为非重复字符串添加后缀。但两者都适用于我的目的。干杯!
        【解决方案4】:

        假设您的数据(按Column1 排序)位于名为tab 的对象中。首先创建一个游程对象

        c1.rle <- rle(tab$Column1)
        c1.rle
        ##lengths: int [1:4] 2 2 1 1
        ##values : int [1:4] 1 2 3 4
        

        这为您提供Column1 的值以及每个元素的相应出现次数。然后使用该信息创建具有唯一标识符的新列:

        tab$Column1.new <- paste0(rep(c1.rle$values, times = c1.rle$lengths), "_",
                unlist(lapply(c1.rle$lengths, seq_len)))
        

        不确定,如果这适合您的情况,但您也可以将 Column1Column2 粘贴在一起,以创建唯一标识符...

        【讨论】:

          猜你喜欢
          • 2015-09-25
          • 1970-01-01
          • 1970-01-01
          • 2023-02-02
          • 1970-01-01
          • 2017-05-26
          • 2018-11-17
          • 1970-01-01
          相关资源
          最近更新 更多