如何用在R中具有特定值范围的NA替换异常值?

时间:2016-10-24 03:50:06

标签: r replace range lapply outliers

我有气候数据,我试图用NA替换异常值。 我没有使用boxplot(x)$out是因为我有一系列的值可以用来计算异常值。

temp_range <- c(-15, 45)
wind_range <- c(0, 15)
humidity_range <- c(0, 100)

我的数据框看起来像这样

df with outliers

(我根据范围强调了应该用NA替换的值。)

因此temp1temp2异常值必须根据NA替换为temp_rangewind&#39}的异常值应替换为{{ 1}}根据NA,最后wind_range的异常值必须根据humidity替换为NA

以下是我所得到的:

humidity_range

我为每个范围执行代码的最后一部分(替换)。有没有办法简化它,所以我可以避免大量的重复?

最后,让我们说df <- read.csv2("http://pastebin.com/raw/vwqBu2M5", stringsAsFactors = FALSE) df[,2:5] = apply(df[,2:5], 2, function(x) as.numeric(x)) #Ranges temp_range <- c(-15, 45) wind_range <- c(0, 15) humidity_range <- c(0, 100) #Function to detect outlier in_interval <- function(x, interval){ stopifnot(length(interval) == 2L) interval[1] <= x & x <= interval[2] } #Replace outliers according to temp_range cols <- c('temp1', 'temp2') df[, cols] <- lapply(df[, cols], function(x) { x[in_interval(x, temp_range)==FALSE] <- NA x }) 这会向我发出警告,并用常量替换整个 wind 列。

cols <- c('wind')

有什么建议吗?

3 个答案:

答案 0 :(得分:1)

要更加动态地执行此操作,请使用字典:具有与每个变量关联的异常值的数据框。

这里我在R中创建它,但在csv中使用它会更实际,因此您可以轻松编辑它。

df <- read.csv2("http://pastebin.com/raw/vwqBu2M5", stringsAsFactors = FALSE)

df[,2:5] = apply(df[,2:5], 2, function(x) as.numeric(x))


df_dict <- data.frame(variable = c("temp1", "temp2", "wind", "humidity"), 
                       out_low = c(-15, -15, 0, 0), 
                       out_high =c(45, 45, 15, 100))

for (var in df_dict$variable) {

  df[[var]][df[[var]] < df_dict[df_dict$variable == var, ]$out_low | df[[var]] > df_dict[df_dict$variable == var, ]$out_high] <- NA

}

答案 1 :(得分:0)

我认为你使它变得比它需要的更复杂。您可以使用逻辑向量有选择地仅替换变量中的某些值:

df <- read.csv2("http://pastebin.com/raw/vwqBu2M5", stringsAsFactors = FALSE)

df[,2:5] = apply(df[,2:5], 2, function(x) as.numeric(x))

#Ranges
temp_range <- c(-15, 45)
wind_range <- c(0, 15)
humidity_range <- c(0, 100)

df$temp1[df$temp1 < temp_range[1] | df$temp1 > temp_range[2]] <- NA
df$temp2[df$temp2 < temp_range[1] | df$temp2 > temp_range[2]] <- NA
df$wind[df$wind < wind_range[1] | df$wind > wind_range[2]] <- NA
df$humidity[df$humidity < humidity_range[1] | df$humidity > humidity_range[2]] <- NA

基本上你所做的就是采用变量,创建一个逻辑向量,只选择范围之外的值,并用NA

替换这些值

这将为您提供以下内容(与您的图片不完全匹配,但根据您的范围数字看似正确):

                  time temp2 wind humidity temp1
1  2006-11-22 22:00:00    NA 0.00    56.95 23.88
2  2006-11-22 23:00:00  15.5 0.00    58.21 23.93
3  2006-11-23 00:00:00    NA   NA    62.95 23.81
4  2006-11-23 01:00:00  12.0 0.30    70.15    NA
5  2006-11-23 02:00:00  35.0 0.07    76.46 21.63
6  2006-11-23 03:00:00  12.0 0.79       NA 21.81
7  2006-11-23 04:00:00  35.0 0.50    69.11 21.04
8  2006-11-23 05:00:00  14.0 0.37    71.86 20.32
9  2006-11-23 06:00:00  -9.0 0.26    70.97 20.50
10 2006-11-23 07:00:00    NA 0.03    78.02    NA

答案 2 :(得分:0)

您可以定义一个功能

wi.Resize(width:200, height:200, preserveAspectRatio:false, preventEnlarge:false);

然后对于每一列,您可以将此函数称为

check_inRange <- function(col, range) {
   df[col] >= range[1] & df[col] <= range[2]
}

这会将超出范围的各列中的所有值替换为df[!check_inRange("temp1", temp_range), "temp1"] <- NA df[!check_inRange("temp2", temp_range), "temp2"] <- NA df[!check_inRange("wind", wind_range), "wind"] <- NA df[!check_inRange("humidity", humidity_range), "humidity"] <- NA