1

我有许多不同的表,我想在 R 中编写一个函数,其中:

表 1:

          coordinates var1.pred  var1.var observed    residual      zscore fold
1  (2579410, 1079720)  5.057024 0.4325275    5.468  0.41097625  0.62489903    1
2  (2579330, 1079730)  5.329797 0.3945041    4.498 -0.83179667 -1.32431534    2
3  (2579260, 1079770)  4.788211 0.5576228    5.114  0.32578861  0.43628035    3
4  (2579930, 1080030)  5.067753 0.4972365    4.764 -0.30375347 -0.43076434    4
5  (2579700, 1079770)  5.116632 0.5792768    4.626 -0.49063190 -0.64463327    5
6  (2579540, 1079640)  4.865667 0.6122453    6.522  1.65633254  2.11682434    6
7  (2579860, 1079880)  5.139779 0.4655840    4.856 -0.28377887 -0.41589245    7

如果“观察到”的值超出了以下两个值的容差,则将其标记为异常值:

var1.pred+(1.96*sqrt(var1.var))
var1.pred-(.96*sqrt(var1.var))

换句话说:

      if   
   var1.pred-(1.96*sqrt(var1.var)) < 'observed' <  var1.pred-(1.96*sqrt(var1.var))

结果正常,否则结果异常。

此外,列的名称相同,表名称为 1,2,3 .... 。

 dat <- structure(list(coordinates = structure(c(3L, 2L, 1L, 7L, 5L,                                
     4L, 6L), .Label = c("(2579260, 1079770)", "(2579330, 1079730)",                                
     "(2579410, 1079720)", "(2579540, 1079640)", "(2579700, 1079770)",                              
     "(2579860, 1079880)", "(2579930, 1080030)"), class = "factor"),                                
         var1.pred = c(5.057024, 5.329797, 4.788211, 5.067753, 5.116632,                            
         4.865667, 5.139779), var1.var = c(0.4325275, 0.3945041, 0.5576228,                         
         0.4972365, 0.5792768, 0.6122453, 0.465584), observed = c(5.468,                            
         4.498, 5.114, 4.764, 4.626, 6.522, 4.856), residual = c(0.41097625,                        
         -0.83179667, 0.32578861, -0.30375347, -0.4906319, 1.65633254,                              
         -0.28377887), zscore = c(0.62489903, -1.32431534, 0.43628035,                              
         -0.43076434, -0.64463327, 2.11682434, -0.41589245), fold = 1:7), .Names = c("coordinates", 
     "var1.pred", "var1.var", "observed", "residual", "zscore", "fold"                              
     ), row.names = c(NA, -7L), class = "data.frame")  
4

3 回答 3

5

这应该有效:

dat$outlier = with(as.data.frame(dat), 
                   ifelse(observed > (var1.pred + (.95*var1.var)) | # | = OR
                          observed < (var1.pred - (.95*var1.var)),
             "outlier", "normal"))

我的代码与您的描述有点不同,因为我检查值是否在范围之外,而不是在范围内。以上在您的示例代码上运行:

> dat
         coordinates var1.pred  var1.var observed   residual     zscore fold
1 (2579410, 1079720)  5.057024 0.4325275    5.468  0.4109762  0.6248990    1
2 (2579330, 1079730)  5.329797 0.3945041    4.498 -0.8317967 -1.3243153    2
3 (2579260, 1079770)  4.788211 0.5576228    5.114  0.3257886  0.4362803    3
4 (2579930, 1080030)  5.067753 0.4972365    4.764 -0.3037535 -0.4307643    4
5 (2579700, 1079770)  5.116632 0.5792768    4.626 -0.4906319 -0.6446333    5
6 (2579540, 1079640)  4.865667 0.6122453    6.522  1.6563325  2.1168243    6
7 (2579860, 1079880)  5.139779 0.4655840    4.856 -0.2837789 -0.4158925    7
  outlier
1 outlier                                                                   
2 outlier                                                                   
3  normal                                                                   
4  normal                                                                   
5  normal                                                                   
6 outlier                                                                   
7  normal 
于 2013-01-28T13:24:16.813 回答
5

保罗的回答都很好,只是建议略有不同。

> dat
         coordinates var1.pred  var1.var observed   residual     zscore fold
1 (2579410, 1079720)  5.057024 0.4325275    5.468  0.4109762  0.6248990    1
2 (2579330, 1079730)  5.329797 0.3945041    4.498 -0.8317967 -1.3243153    2
3 (2579260, 1079770)  4.788211 0.5576228    5.114  0.3257886  0.4362803    3
4 (2579930, 1080030)  5.067753 0.4972365    4.764 -0.3037535 -0.4307643    4
5 (2579700, 1079770)  5.116632 0.5792768    4.626 -0.4906319 -0.6446333    5
6 (2579540, 1079640)  4.865667 0.6122453    6.522  1.6563325  2.1168243    6
7 (2579860, 1079880)  5.139779 0.4655840    4.856 -0.2837789 -0.4158925    7

> dat$label <- ifelse(dat$observed < dat$var1.pred-(1.96*sqrt(dat$var1.var)) |  dat$observed > dat$var1.pred+(1.96*sqrt(dat$var1.var)), "outlier", "normal" )

> dat
         coordinates var1.pred  var1.var observed   residual     zscore fold   label
1 (2579410, 1079720)  5.057024 0.4325275    5.468  0.4109762  0.6248990    1  normal
2 (2579330, 1079730)  5.329797 0.3945041    4.498 -0.8317967 -1.3243153    2  normal
3 (2579260, 1079770)  4.788211 0.5576228    5.114  0.3257886  0.4362803    3  normal
4 (2579930, 1080030)  5.067753 0.4972365    4.764 -0.3037535 -0.4307643    4  normal
5 (2579700, 1079770)  5.116632 0.5792768    4.626 -0.4906319 -0.6446333    5  normal
6 (2579540, 1079640)  4.865667 0.6122453    6.522  1.6563325  2.1168243    6 outlier
7 (2579860, 1079880)  5.139779 0.4655840    4.856 -0.2837789 -0.4158925    7  normal

更新:顺便说一句,如果您正在寻找执行此操作的函数,并且当您提到列名始终相同时,您可以将函数编写为

checkRange <- function(dat) {
  dat$label <- ifelse(dat$observed < dat$var1.pred-(1.96*sqrt(dat$var1.var)) |  dat$observed   dat$var1.pred+(1.96*sqrt(dat$var1.var)), "outlier", "normal" )
  return(dat)
}
> dat <- checkRange(dat)

> dat
         coordinates var1.pred  var1.var observed   residual     zscore fold   label
1 (2579410, 1079720)  5.057024 0.4325275    5.468  0.4109762  0.6248990    1  normal
2 (2579330, 1079730)  5.329797 0.3945041    4.498 -0.8317967 -1.3243153    2  normal
3 (2579260, 1079770)  4.788211 0.5576228    5.114  0.3257886  0.4362803    3  normal
4 (2579930, 1080030)  5.067753 0.4972365    4.764 -0.3037535 -0.4307643    4  normal
5 (2579700, 1079770)  5.116632 0.5792768    4.626 -0.4906319 -0.6446333    5  normal
6 (2579540, 1079640)  4.865667 0.6122453    6.522  1.6563325  2.1168243    6 outlier
7 (2579860, 1079880)  5.139779 0.4655840    4.856 -0.2837789 -0.4158925    7  normal
于 2013-01-28T13:29:36.673 回答
0

哈米德给你一个好消息。已经存在使这样的工作非常容易的软件包。我个人最喜欢这种工作的是“plyr”包。要将 [tolerances] 列添加到数据框中,您将使用“ddply”函数(输入是数据框,输出是数据框,因此“ply”的“dd”前缀)。

library(plyr)
ddply(dat, .(fold), mutate, tolerances=ifelse(observed < (var1.pred - 0.95 * var1.var)|observed > (var1.pred + 0.95 * var1.var),"Outlier","Normal"))

我将为后代解释这些函数参数中的每一个,以便您可以根据需要调整它们。我们告诉 'ddply' 从数据框 [dat] 加载数据,并且我们使用列 [fold] 作为主键。我们必须告诉 'ddply' 使用什么作为键,因为它会自动尝试聚合适合键的数据。使用 [fold] 确保我们得到每一行的结果。接下来,我们使用“mutate”函数,它保留所有原始数据,但添加我们指定的新列。最后,我们指定了一个新列 [tolerances],其中包含一个“ifelse”语句,用于检查 [observed] 值是小于容差下限还是高于容差上限。如果为真,则值为“异常值”,如果为假,则值为“正常”。

于 2013-01-28T13:35:09.727 回答