2016-10-24 8 views
1

기후 데이터가 있는데 이상한 데이터를 NA으로 대체하려고합니다. boxplot(x)$out은 아웃 라이어를 계산할 값의 범위가 있기 때문에 사용하지 않습니다.R에서 특정 범위의 값을 갖는 NA로 이상 치를 대체하는 방법?

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

내 dataframe이

df with outliers

(나는 NA는 범위에 따라 교체해야합니다 값을 강조했다.)과 같은

그래서 temp1temp2 아웃 라이어가 NA로 교체해야합니다 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 

기본적으로 당신이하고있는 모두가 그 값을 변수를 고려하여 범위를 벗어나는 유일한 값을 선택하는 논리 벡터를 생성 및 교체 : 당신은 선택적 변수에 특정 값을 대체 할 논리적 벡터를 사용할 수 있습니다

    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

결과가 출력과 유사해야합니다. 첫 번째와 두 번째 교체 라인을 lapply에서 할 수 있습니까? 그것들은 매우 유사하게 보이고 샘플을 게시했습니다. 'temp_range'를 기반으로 한 컬럼이 더 많아서이 대체 라인의 크기가 늘어나고 더 동적으로 처리하기를 원합니다. –

0

당신은 함수를 정의 할 수 있습니다,

: NA

으로 그것은 당신에게를 (아주 이미지와 일치하지만, 번호가 사용자의 범위에 따라 올바른 보이지 않는) 다음과 같은 줄 것이다

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' 컬럼의 outlier가 아니기 때문에 0이 대체되지 않습니다. 첨부 된 이미지) –

+0

@ 마틴 알았어. 대답을 올렸어. 또한 'temp2' 열의 이미지에서 강조 표시되어서는 안됩니다. 범위 안에있는 그대로. (-15, 45) 그렇지 않나요? –

+1

네 말이 맞아. 업데이트 됨. Btw 좋은 솔루션. 이 함수는 매력처럼 작동하지만 다른 데이터 프레임이 있으면 약간 하드 코딩 된 것처럼 보입니다. 먼저 동일한 기능을 사용하여 이상치를 표시하고 색상을 조정 한 다음 NA로 대체 할 수 있으므로 작업하겠습니다. –