4

X

Team Date       Score
A    1-1-2012   80
A    1-2-2012   90
A    1-3-2012   50
A    1-4-2012   40   
B    1-1-2012   100
B    1-2-2012   60
B    1-3-2012   30
B    1-4-2012   70
etc

我需要并且可以将此数据框转换为每个团队的一行宽数据框,并将所有观察结果和日期作为标题:

xx

Team 1-1-2012 1-2-2012  1-3-2012 1-4-2012
A    80       90        50        40
B    100     60         30        70  

我需要计算每一行的平均值和标准差,我可以这样做:

xx

Team 1-1-2012 1-2-2012  1-3-2012 1-4-2012  mean   sd
A    80       90        50        40       75    20
B    100     60         30        70       55    10 

考虑到我在数据框 xx 中有数千行。我想对每个单元格进行计算,如下所示:

如果 abs(xx-Mean) > 3*SD,创建一个计数器列名并增加值。这个想法是将每个观察结果与平均值和 sd 进行比较,如果给定团队的每个观察结果都匹配 - abs(xx-Mean) > 3*SD,则增加计数器。检查每个单元格后,我想查看每个团队的每个计数器,并获得计数器值最高的前十名高团队。基本上我正在尝试检测最多的异常值。一旦获得前 10 名团队名称,我想在数据框 x 上绘制他们的时间序列数据。

我希望我不会让这变得比它应该的更复杂。不确定,R 已经具有对每个单元格进行计算的功能。任何想法如何实现这一点表示赞赏?

4

2 回答 2

6

我会将您的数据保留为长格式并使用plyr,data.table或任何其他拆分-应用-组合工具来计算您的统计数据。这是我plyr用于该任务的方式:

#Your data
dat <- read.table(text = "Team Date       Score
A    1-1-2012   80
A    1-2-2012   90
A    1-3-2012   50
A    1-4-2012   40   
B    1-1-2012   100
B    1-2-2012   60
B    1-3-2012   30
B    1-4-2012   70", header = TRUE)

library(plyr)

#Compute mean and sd by team
dat <- ddply(dat, .(Team), transform, mean = mean(Score), sd = sd(Score))
#Your outlier threshold
dat <- transform(dat, outlier = abs(Score - mean) > 3*sd)
#Cumulative sum by team
dat <- ddply(dat, .(Team), transform, cumsumOutlier = cumsum(outlier))

将此作为输出(与您的示例不匹配,但可能是您的真实数据):

 Team     Date Score mean       sd outlier cumsumOutlier
1    A 1-1-2012    80   65 23.80476   FALSE             0
2    A 1-2-2012    90   65 23.80476   FALSE             0
3    A 1-3-2012    50   65 23.80476   FALSE             0
4    A 1-4-2012    40   65 23.80476   FALSE             0
5    B 1-1-2012   100   65 28.86751   FALSE             0
6    B 1-2-2012    60   65 28.86751   FALSE             0
7    B 1-3-2012    30   65 28.86751   FALSE             0
8    B 1-4-2012    70   65 28.86751   FALSE             0
于 2012-10-15T01:44:00.187 回答
5

long-formatdata.table方法

DT <- read.table( 'clipboard', header = T)
library(data.table)
DT <- as.data.table(DT)
DT[, mean.score := mean(Score), by = Team]
##    Team     Date Score mean.score
## 1:    A 1-1-2012    80         65
## 2:    A 1-2-2012    90         65
## 3:    A 1-3-2012    50         65
## 4:    A 1-4-2012    40         65
## 5:    B 1-1-2012   100         65
## 6:    B 1-2-2012    60         65
## 7:    B 1-3-2012    30         65
## 8:    B 1-4-2012    70         65
DT[, sd.score := sd(Score), by = Team]
##    Team     Date Score mean.score sd.score
## 1:    A 1-1-2012    80         65 23.80476
## 2:    A 1-2-2012    90         65 23.80476
## 3:    A 1-3-2012    50         65 23.80476
## 4:    A 1-4-2012    40         65 23.80476
## 5:    B 1-1-2012   100         65 28.86751
## 6:    B 1-2-2012    60         65 28.86751
## 7:    B 1-3-2012    30         65 28.86751
## 8:    B 1-4-2012    70         65 28.86751
DT[, outlier := abs(Score-mean.score) > 3 * sd.score, by = Team]
##    Team     Date Score mean.score sd.score outlier
## 1:    A 1-1-2012    80         65 23.80476   FALSE
## 2:    A 1-2-2012    90         65 23.80476   FALSE
## 3:    A 1-3-2012    50         65 23.80476   FALSE
## 4:    A 1-4-2012    40         65 23.80476   FALSE
## 5:    B 1-1-2012   100         65 28.86751   FALSE
## 6:    B 1-2-2012    60         65 28.86751   FALSE
## 7:    B 1-3-2012    30         65 28.86751   FALSE
## 8:    B 1-4-2012    70         65 28.86751   FALSE

或者,一步

DT[, outlier := abs(Score-mean(Score)) > 3 *  sd(Score), by = Team]

添加异常值的数量(逻辑变量的总和将强制为 0,1)

DT[, sum.outlier := sum(outlier), by = Team]
于 2012-10-15T01:40:05.090 回答