2013-06-13 3 views
6

У меня есть некоторые данные:Добавьте столбец рангов

test <- data.frame(A=c("aaabbb", 
"aaaabb", 
"aaaabb", 
"aaaaab", 
"bbbaaa") 
) 

и так далее. Все элементы имеют одинаковую длину и уже отсортированы, прежде чем я их получу.

Мне нужно создать новый столбец рядов «Первый», «Второй», «Третий», после чего можно оставить пустым, и ему необходимо учесть связи. Таким образом, в описанном выше случае, я хотел бы получить следующий вывод:

A  B 
aaabbb First 
aaaabb Second 
aaaabb Second 
aaaaab Third 
bbbaaa 
bbbbaa 

Я смотрел на ранге() и некоторые другие должности, которые использовали его, но я не смог заставить его делать то, что я искал.

ответ

3

Как об этом:

test$B <- match(test$A , unique(test$A)[1:3]) 
test 
     A B 
1 aaabbb 1 
2 aaaabb 2 
3 aaaabb 2 
4 aaaaab 3 
5 bbbaaa NA 
6 bbbbaa NA 

Один из многих способов сделать это. Возможно, не лучший, но тот, который с легкостью приходит на ум и довольно интуитивно понятен. Вы можете использовать unique, потому что вы получаете данные, предварительно отсортированные.

Поскольку данные сортируются другой подходящей функции стоит рассмотреть rle, хотя это немного более тупые в этом примере:

rnk <- rle(as.integer(df$A))$lengths 
rnk 
# [1] 1 2 1 1 1 
test$B <- c(rep(1:3 , times = rnk[1:3]) , rep(NA, sum(rnk[-c(1:3)]))) 

rle вычисляет длины (и ценности, которые мы на самом деле не заботиться о здесь) из пробеги равных значений в векторе - так что это работает, потому что ваши данные уже отсортированы.

И если вы не имеют иметь пробелы после третьего занимает пункта это еще проще (и более читаемым):

test$B <- rep(1:length(rnk),times=rnk) 
+0

Я не знаю, я думаю, что это чертовски хорошо. – thelatemail

+0

@thelatemail LOL, приветствия. Полагаю, что так. Я также думал о 'rle', поскольку данные сортируются. Кажется целесообразным, поэтому я добавлю его в качестве альтернативы. –

+0

Это именно то, что я искал. Благодаря! – pak

3

Это похоже на хорошее применение для факторов:

test$B <- as.numeric(factor(test$A, levels = unique(test$A))) 

cumsum также приходит на ум, когда мы добавим 1 каждый раз при изменении значения:

test$B <- cumsum(c(TRUE, tail(test$A, -1) != head(test$A, -1))) 

(Как @Simon сказал, есть много способов сделать это ...)

+0

+1 для метода смещения головок и хвостов. Умная. –

+1

Это тоже полезно, особенно если все должно быть оценено. В этом конкретном случае это был только верх 3. Спасибо. Иногда я думаю, что здорово, что есть так много способов сделать что-то, и иногда это заставляет меня хотеть загорать мои волосы. – pak

+0

@flodel. Просто проверил ваш первый ответ (используя факторы) по некоторым моим данным и понял, что он не работает правильно во всех случаях. Это потому, что можно сказать, что тест $ A [10] ** выглядит **, как если бы он был равен тесту $ A [6], причем промежуточные элементы были разными. Рассмотрение их как факторов приводит к равенству, где это может не быть, в данном случае. – pak

Смежные вопросы