如何用 R 中具有特定值范围的 NA 替换异常值?
How to replace outliers with NA having a particular range of values in R?
我有气候数据,我正在尝试用 NA
替换异常值。
我没有使用 boxplot(x)$out
是因为我有一系列值可以考虑计算异常值。
temp_range <- c(-15, 45)
wind_range <- c(0, 15)
humidity_range <- c(0, 100)
我的数据框看起来像这样
df with outliers
(我突出显示了根据范围应替换为 NA 的值。)
所以temp1
和temp2
异常值必须根据temp_range
替换成NA
,wind
的异常值应该替换成[=13] =] 根据 wind_range
最后 humidity
的异常值必须根据 humidity_range
.
替换为 NA
这是我得到的:
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
})
我正在为每个范围执行代码的最后一部分(替换)。有没有办法简化它,这样我就可以避免很多重复?
最后一件事,让我们说 cols <- c('wind')
这会给我一个警告并用常量替换整个 wind 列。
Warning message:
In `[<-.data.frame`(`*tmp*`, , cols, value = list(23.88, 23.93, :
provided 10 variables to replace 1 variables
有什么建议吗?
我认为你让它变得比需要的更复杂。您可以使用逻辑向量有选择地仅替换变量中的某些值:
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
你可以定义一个函数,
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
这将替换各个列中超出 NA
范围的所有值
要更动态地做到这一点,请使用字典:一个数据框,其离群值与每个变量相关联。
这里我在 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
}
我有气候数据,我正在尝试用 NA
替换异常值。
我没有使用 boxplot(x)$out
是因为我有一系列值可以考虑计算异常值。
temp_range <- c(-15, 45)
wind_range <- c(0, 15)
humidity_range <- c(0, 100)
我的数据框看起来像这样
df with outliers
(我突出显示了根据范围应替换为 NA 的值。)
所以temp1
和temp2
异常值必须根据temp_range
替换成NA
,wind
的异常值应该替换成[=13] =] 根据 wind_range
最后 humidity
的异常值必须根据 humidity_range
.
NA
这是我得到的:
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
})
我正在为每个范围执行代码的最后一部分(替换)。有没有办法简化它,这样我就可以避免很多重复?
最后一件事,让我们说 cols <- c('wind')
这会给我一个警告并用常量替换整个 wind 列。
Warning message:
In `[<-.data.frame`(`*tmp*`, , cols, value = list(23.88, 23.93, :
provided 10 variables to replace 1 variables
有什么建议吗?
我认为你让它变得比需要的更复杂。您可以使用逻辑向量有选择地仅替换变量中的某些值:
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
你可以定义一个函数,
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
这将替换各个列中超出 NA
要更动态地做到这一点,请使用字典:一个数据框,其离群值与每个变量相关联。
这里我在 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
}