Переименование повторяющихся строк в R

У меня есть кадр данных 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

Любые идеи о том, как это сделать, будут оценены.

Ваше здоровье,

Антти


person Antti    schedule 20.05.2013    source источник


Ответы (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)))

Не уверен, что это уместно в вашей ситуации, но вы также можете просто соединить Column1 и Column2, чтобы создать уникальный идентификатор...

person adibender    schedule 20.05.2013

Может быть немного больше обходного пути, но часть этого может быть более полезной и простой для кого-то с не совсем такими же потребностями. make.names с атрибутом unique=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" 

Как я уже сказал, здесь больше обходного пути, но есть несколько вариантов.

person Cão    schedule 27.10.2017

@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
person Ferroao    schedule 25.08.2019

person    schedule
comment
На самом деле это более точное решение, поскольку я не хотел иметь суффиксы для неповторяющихся строк. Но оба хорошо работают для моих целей. Ваше здоровье! - person Antti; 20.05.2013