Автоматическое создание группы в R или SQL

#sql #r

#sql #r

Вопрос:

У меня есть фрейм данных R со столбцом AS_ID, как указано ниже:

 AS_ID
A8653654
B7653655
C5653650
C5653650
A8653654
D1658645
D1658645
C5653650
C5653650
D1658645
C5653650
E4568640
F796740
A8653654
F796740
E4568640
 

Я пытаюсь сгруппировать похожие записи как A1, A2, A3 и так далее. Например, все записи, имеющие AS_ID как «A8653654», должны быть сгруппированы как A1 и могут быть введены в новый столбец, как указано ниже:

 AS_ID   AS
A8653654    A1
B7653655    A2
C5653650    A3
C5653650    A3
A8653654    A1
D1658645    A4
D1658645    A4
C5653650    A3
C5653650    A3
D1658645    A4
C5653650    A3
E4568640    A5
F796740 A6
A8653654    A1
F796740 A6
E4568640    A5
 

Меня устраивает либо R, либо oracle code, поскольку я тоже могу писать SQL-код на R. Любая помощь будет высоко оценена. Мои данные немного более динамичны по сравнению с тем, что я привел в примере данных выше. Общий код поможет больше.

Ответ №1:

Если вы прочитали эти значения в R data.frame, скорее всего, они уже относятся к классу «factor». Если нет, вы можете преобразовать их в фактор. Но каждому значению фактора уже автоматически присваивается уникальный целочисленный идентификатор. Вот пример data.frame

 dd<-read.table(text=c("A8653654", "B7653655", "C5653650", "C5653650", "A8653654", 
  "D1658645", "D1658645", "C5653650", "C5653650", "D1658645", "C5653650", 
  "E4568640", "F796740", "A8653654", "F796740", "E4568640"), col.names="AS_ID")
 

Обратите внимание, что

 class(dd$AS_ID)
# [1] "factor"
 

Если бы это был символ, вы могли бы сделать

 dd$AS_ID <- factor(dd$AS_ID)
 

Чтобы получить уникальные идентификаторы, просто используйте as.numeric , а затем вставьте A перед этим

 dd <- cbind(dd, AS=paste0("A",as.numeric(dd$AS_ID)))
 

и это дает

 #> head(dd)
     AS_ID AS
1 A8653654 A1
2 B7653655 A2
3 C5653650 A3
4 C5653650 A3
5 A8653654 A1
6 D1658645 A4
 

Ответ №2:

Вы можете получить идентификатор группы в Oracle с помощью dense_rank() :

 select AS_ID, dense_rank() over (partition by AS_ID order by AS_ID)
from table t;
 

Если вы хотите 'A' , чтобы впереди, затем объедините его:

 select AS_ID, 'A' || dense_rank() over (partition by AS_ID order by AS_ID)