Добавление повторного индекса для факторов во фрейме данных - PullRequest
2 голосов
/ 27 мая 2011

У меня есть фрейм данных, в который я хочу добавить индекс, например, 1 ... n для каждого фактора в моем фрейме данных.Вот пример с некоторыми фиктивными данными.

factor
a        
a         
a         
a        
a        
b        
b        
b        
b        
b
c
c
c
c

Я хотел бы добавить дополнительный столбец, который добавляет индекс 1 к n для каждого фактора отдельно.Результирующий фрейм данных будет выглядеть так:

factor  index
a        1
a        2 
a        3 
a        4
a        5
b        1
b        2
b        3
b        4
b        5 
c        1
c        2
c        3
c        4

Может кто-нибудь объяснить, как это сделать?Заранее спасибо.

Ответы [ 4 ]

14 голосов
/ 27 мая 2011

Вы можете использовать ave функцию:

your_data <- data.frame(
     factor=factor(rep(letters[1:3], times = c(5,5,4)))
)
your_data$index <- ave(rep(NA, nrow(your_data)), your_data$factor, FUN=seq_along)
3 голосов
/ 27 мая 2011

Один из способов:

unlist(lapply(split(x, x), seq_along))

, где x - это ваш фактор как вектор.

R> x <- factor(rep(letters[1:3], times = c(5,5,4))) ## your data
R> data.frame(factor = x, index = unlist(lapply(split(x, x), seq_along), 
+             use.names = FALSE))
   factor index
1       a     1
2       a     2
3       a     3
4       a     4
5       a     5
6       b     1
7       b     2
8       b     3
9       b     4
10      b     5
11      c     1
12      c     2
13      c     3
14      c     4

Другой способ в аналогичной теме - использовать table() иseq_len():

unlist(sapply(table(x), seq_len), use.names = FALSE)

И еще один способ - использовать кодировку длин серий через rle():

R> rle(as.character(x))$lengths
[1] 5 5 4

, которую мы можем вставить в код sapply() вместоtable() вызов:

R> unlist(sapply(rle(as.character(x))$lengths, seq_len), use.names = FALSE)
 [1] 1 2 3 4 5 1 2 3 4 5 1 2 3 4
1 голос
/ 27 мая 2011

Попробуйте следующую функцию:

 facSeq <- function(x){
     x.l <-length(x)
     x.f.l <- length(levels(x))
     sapply(1:x.f.l,function(y) cumsum(as.integer(x)%in%y))[1:x.l+x.l*(as.integer(x)-1)]
 }

Тестирование:

fac1 <- factor(rep(letters[1:3],each=5))

> data.frame(fac1,index=facSeq(fac1))
   fac1 index
1     a     1
2     a     2
3     a     3
4     a     4
5     a     5
6     b     1
7     b     2
8     b     3
9     b     4
10    b     5
11    c     1
12    c     2
13    c     3
14    c     4
15    c     5

Более интересный пример:

fac2 <- factor(sample(letters[1:5],20,replace=T))

> data.frame(fac2,index=facSeq(fac2))
   fac2 index
1     a     1
2     a     2
3     d     1
4     b     1
5     a     3
6     e     1
7     e     2
8     a     4
9     c     1
10    e     3
11    b     2
12    d     2
13    b     3
14    e     4
15    e     5
16    d     3
17    c     2
18    e     6
19    b     4
20    d     4
0 голосов
/ 24 апреля 2017

В базе R с использованием sequence и table:

df$index <- sequence(table(df$factor))

   # factor index
# 1       a     1
# 2       a     2
# 3       a     3
# 4       a     4
# 5       a     5
# 6       b     1
# 7       b     2
# 8       b     3
# 9       b     4
# 10      b     5
# 11      c     1
# 12      c     2
# 13      c     3
# 14      c     4

Данные

df <- data.frame(factor=factor(rep(letters[1:3], times = c(5,5,4))))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...