df <- read.table(con <- textConnection("USER_A USER_B SCORE
1 6 0.2
1 7 0.1
1 10 0.15
2 6 0.2
2 9 0.12
3 8 0.15
3 9 0.3
"), header = TRUE)
close(con)
Один из способов - разделить данные:
sdf <- with(df, split(SCORE, f = USER_A))
lapply(sdf, rank)
Последняя строка дает:
> lapply(sdf, rank)
$`1`
[1] 3 1 2
$`2`
[1] 2 1
$`3`
[1] 1 2
Альтернативой является использование aggregate()
как в:
aggregate(SCORE ~ USER_A, data = df, rank)
Что возвращает:
> (foo <- aggregate(SCORE ~ USER_A, data = df, rank))
USER_A SCORE
1 1 3, 1, 2
2 2 2, 1
3 3 1, 2
Но вывод здесь немного другой, теперь у нас есть фрейм данных со вторым компонентом SCORE
, представляющим собой список, точно так же, как и выводимая версия lapply()
:
> str(foo)
'data.frame': 3 obs. of 2 variables:
$ USER_A: int 1 2 3
$ SCORE :List of 3
..$ 0: num 3 1 2
..$ 1: num 2 1
..$ 2: num 1 2
> foo$SCORE
$`0`
[1] 3 1 2
$`1`
[1] 2 1
$`2`
[1] 1 2