2013-04-16 3 views
1

Вот пример моих данных:Группировка данных в R для выполнения функции

  id score 
1   82 0.50000 
2   82 0.39286 
3   82 0.56250 
4   328 0.50000 
5   328 0.67647 
6   328 0.93750 
7   328 0.91667 

Я хочу сделать столбец скользящих средних-х баллов по каждому идентификатору.

Поэтому мне нужно каким-то образом сгруппировать данные по идентификатору затем применить функцию МА к этим сгруппированным данным и затем вывод как еще один столбец «MA_score»

Я хотел бы мой выход выглядеть следующим образом:

  id score MA_score 
1   82 0.50000 NULL 
2   82 0.39286 0.xxxx 
3   82 0.56250 NULL 
4   328 0.50000 NULL 
5   328 0.67647 0.yyyy 
6   328 0.93750 0.qqqq 
7   328 0.91667 NULL 
+0

Можете ли вы дать образец вывода? – Nishanth

+0

Не скользящее среднее должно иметь размер окна? – Arun

+0

вы должны дать воспроизводимый образец данных и образец вывода – ECII

ответ

4

Вы можете использовать split и rollapply из пакета zoo как один из многих способов приблизиться к этому. Обратите внимание, что в приведенном ниже примере я устанавливаю ширину функции rollapply равным 1, поэтому он просто возвращает каждое значение. Для ширины, превышающей единицу, она примет среднее значение этого числа значений.

require(zoo) 
sapply(split(df , df$id) , function(x) rollapply(x , width = 1 , align = 'left' , mean)) 
#Note that by setting width = 1 we just return the value 
$`82` 
    id score 
[1,] 82 0.50000 
[2,] 82 0.39286 
[3,] 82 0.56250 

$`328` 
     id score 
[1,] 328 0.50000 
[2,] 328 0.67647 
[3,] 328 0.93750 
[4,] 328 0.91667 

Если мы должны были установить width = 3 вы получите:

$`82` 
    id score 
[1,] 82 0.48512 

$`328` 
     id  score 
[1,] 328 0.7046567 
[2,] 328 0.8435467 

Или вы могли бы использовать агрегат в base R:

aggregate( score ~ id , data = df , function(x) rollapply(x , width = 1 , align = 'left' , mean) ) 
    id        score 
1 82   0.50000, 0.39286, 0.56250 
2 328 0.50000, 0.67647, 0.93750, 0.91667 

Есть довольно много способов сделать это. Я бы точно определить свою скользящую среднюю функцию, хотя, потому что есть много способов вычислить его (проверить, например TTR:::SMA)


Или более простое использование ave:

within(df, { MA_score <- ave(score, id, FUN=function(x) 
       rollmean(x, k=3, na.pad = TRUE))}) 
+0

Довольно интеллектуальное решение, выполняющее все в одной строке кода через 'inside' и' ave'! – fdetsch

2

Вы можете разделить ваши данные по уникальным значениям идентификатора, вычислите среднее значение прокатки (из пакета «зоопарк») для каждого из этих уникальных идентификаторов и добавьте результаты в ваш исходный фрейм данных:

# Required packages 
library(zoo) 

# Data setup 
df <- data.frame(id = c(82, 82, 82, 328, 328, 328, 328), 
       score = c(0.5, 0.39286, 0.5625, 0.5, 0.67647, 0.9375, 0.91667)) 

# Split data by unique IDs 
df.sp <- split(df, df$id) 

# Calculate rolling mean for each unique ID 
df.ma <- lapply(seq(df.sp), function(i) { 
    rollmean(df.sp[[i]]$score, k = 3, na.pad = TRUE) 
}) 

# Append column 'MA_score' to dataframe 
for (i in seq(names(df.sp))) { 
    df[which(df$id == names(df.sp)[i]), "MA_score"] <- df.ma[[i]] 
} 

df 
    id score MA_score 
1 82 0.50000  NA 
2 82 0.39286 0.4851200 
3 82 0.56250  NA 
4 328 0.50000  NA 
5 328 0.67647 0.7046567 
6 328 0.93750 0.8435467 
7 328 0.91667  NA