2016-10-24 4 views
1

気候データがあり、外れ値をNAに置き換えようとしています。 私は外れ値を計算するための値の範囲があるので、boxplot(x)$outを使用していません。特定の範囲の値を持つNAを外れ値に置き換えるには?

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

私のデータフレームは、(私は範囲に応じてNAに置き換えるべき値を強調した。)

のでtemp1temp2外れ値はNAに交換する必要があります。この

df with outliers

のように見えますtemp_rangeによれば、windの外れ値は、に従ってNAに置き換えなければならない、最後に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')と言うと、私は警告をスローし、全体をの列に置き換えます。

Warning message: 
In `[<-.data.frame`(`*tmp*`, , cols, value = list(23.88, 23.93, : 
    provided 10 variables to replace 1 variables 

お勧めはありますか?

答えて

1

の範囲の外にある各列のすべての値を置き換えます

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 

としてこの関数を呼び出すことができますdictionnary:各変数に関連付けられた異常値を持つデータフレームを使用します。

ここでは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 

} 
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 
+0

イメージを更新しました。結果は出力と同じように見えます。願わくばで最初と2番目の交換ラインを行うことは可能ですか?彼らは非常に似ていると私はちょうどサンプルを投稿した、私は 'temp_range'に基づいてより多くの列を持っているので、この交換ラインの量が増加し、私はより動的にそれをやりたいと思います。 –

0

あなたは、

を関数を定義することができます
check_inRange <- function(col, range) { 
    df[col] >= range[1] & df[col] <= range[2] 
} 

、その後、列ごとに、あなたはこれがよりダイナミックにそれを行うにはNA

+0

'check_inRange'関数で条件は' df [col]> = range [1]&df [col] <= range [2] 'でなければならないので、' wind'カラムの外れ値ではないので0を置き換えません添付画像) –

+0

@マーチン大丈夫です。答えをアップしました。また、 'temp2'の画像では35を強調表示しないでください。それが範囲内にあるので。 (-15,45)そうではありませんか? –

+1

あなたはそうです。更新しました。 Btw素晴らしいソリューション。その関数は魅力的に機能しますが、別のデータフレームを持っていれば少しハードコードされています。同じ関数を使って外れ値を最初にプロットし、色を調整した後で、それらをNAで置き換えることができるので、私はその上で作業します。 –

関連する問題