2016-04-04 2 views
3

Глупый пример:Действительно ли R `unique` всегда возвращает значения в том же порядке?

df <- data.frame(group=rep(LETTERS, each=2), value=1:52) 
res <- unlist(lapply(unique(df$group), function(x) mean(subset(df, group==x)$value))) 
names(res) <- unique(df$group) 

Будет res всегда?

A B C D E F G H I J K L M N O P 
1.5 3.5 5.5 7.5 9.5 11.5 13.5 15.5 17.5 19.5 21.5 23.5 25.5 27.5 29.5 31.5 
    Q R S T U V W X Y Z 
33.5 35.5 37.5 39.5 41.5 43.5 45.5 47.5 49.5 51.5 

Может случиться так, что средства, рассчитанные по строке 2, не совпадут с именами в строке 3? Я думаю, это зависит от базовой реализации unique в базе R, но я не уверен, где ее найти.

+5

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

+0

Возможный дубликат [Does unique() сохранить заказ?] (Http://stackoverflow.com/questions/20260835/does-unique-preserve-order) – Scarabee

ответ

10

В соответствии с ?unique:

«уникальный» возвращает вектор, кадр данных или массив как «х», но с дублированных элементов/строк удалены.

Это описание дает полное описание заказа - это будет в том же порядке, что и порядка первых уникальных элементов. (Я предполагаю, что я не вижу, что пространство для маневра @joran видит для другого заказа). Например,

unique(c("B","B","A","C","C","C","B","A")) 

приведет

[1] "B" "A" "C" 

Я считаю, что unique(x) будет вообще быть идентичны (но более эффективно, чем)

x[!duplicated(x)] 

Если вы хотите взглянуть на внутренний код, см here: движущиеся части что-то вроде

k = 0; 
switch (TYPEOF(x)) { 
case LGLSXP: 
case INTSXP: 
for (i = 0; i < n; i++) 
    if (LOGICAL(dup)[i] == 0) 
    INTEGER(ans)[k++] = INTEGER(x)[i]; 
break; 

т. Е. Внутреннее представление является именно тем, что я сказал, что оно проходит через вектор последовательно и заполняет не дублированные элементы. Поскольку в документации явно не гарантируется порядок заказа , возможно, что эта реализация может измениться в будущем, но это почти исчезающе маловероятно.

За то, что вы пытаетесь сделать, есть более простые идиомы R

df <- data.frame(group=rep(LETTERS, each=2), value=1:52) 
a1 <- aggregate(df$value,list(df$group),mean) 

Это возвращает кадр данных две колонки, так что вы можете использовать

setNames(a1[,2],a1[,1]) 

преобразовать его в формат , Или

library(plyr) 
unlist(daply(df,"group",summarise,val=mean(value))) 
+2

Ну, технически, отсортированный список уникальных элементов _is_ "like" x , но с удалением повторяющихся элементов. ;) – joran

+1

Я предполагаю, что интерпретирую документацию так же, как @joran, - что R явно не обещал вернуть FIFO. Консенсус группы достаточно хорош для меня! – fanli

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