2017-12-11 6 views
1

내가 가진 실제 데이터 (및 목표)는 다르지만 재생산 목적으로 타이타닉 데이터 세트를 사용했습니다. 나의 목표는 학급과 성별에 대해 연령 이상치 (1 회 SD)를 작성하는 것입니다.ggplot을 사용하여 효율적인 방법으로 특이 치를 표시

따라서 나는 SD 값을 계산한다했고, 가장 먼저 범위 :

library(dplyr) 
library(ggplot2) 

#Load titanic set 
titanic <- read.csv("titanic_total.csv") 
group <- group_by(titanic, Pclass, Sex) 

#Create outlier ranges 
summarise <- summarise(group, mean=mean(Age), sd=sd(Age)) 
summarise <- as.data.frame(summarise) 
summarise$outlier_max <- summarise$mean + summarise$sd 
summarise$outlier_min <- summarise$mean - summarise$sd 

#Create a key 
summarise$key <- paste0(summarise$Pclass, summarise$Sex) 

#Create a key for the base set 
titanic$key <- paste0(titanic$Pclass, titanic$Sex) 

total_data <- left_join(titanic, summarise, by = "key") 
total_data$outlier <- 0 

다음, 내가 나이가 내부 또는 범위 밖에 있는지 여부를 확인 루프를 사용하는

for (row in 1:nrow(total_data)){ 
if((total_data$Age[row]) > (total_data$outlier_max[row])){ 
    total_data$outlier[row] <- 1 
} else if ((total_data$Age[row]) < (total_data$outlier_min[row])){ 
    total_data$outlier[row] <- 1 
} else { 
    total_data$outlier[row] <- 0 
} 
} 

않는 일부 데이터 정리 중 ...

total_data$Pclass.x <- as.factor(total_data$Pclass.x) 
total_data$outlier <- as.factor(total_data$outlier) 

이제이 코드는 내가 원하는 그림을 제공합니다.

ggplot(total_data, aes(x = Age, y = Pclass.x, colour = outlier)) + geom_point() + 
facet_grid(. ~Sex.x) 

그러나 실제로는이 문제를 해결하는 가장 쉬운 방법은 아닙니다. 이 효율성을 높이기위한 모범 사례를 어떻게 포함 할 수 있는지에 대한 생각.

+0

당신은 벡터화'ifelse'으로'for' 루프를 대체 할 수 : 코드를 추가, 당신은 어떤 방법으로 유지하려는 변수에 따라 달라'total_data의 $의 이상치 <- (total_data, ifelse (나이와 > outlier_max | Age LAP

답변

2

코드를 줄이고 반복성을 줄이는 한 가지 방법은 파이프 덕분에 모든 것을 하나의 절차로 가져 오는 것입니다. 대신 값으로 요약을 생성하는 데이터와이 재 조인, 당신은 기본적으로 하나의 mutate 단계에서이 작업을 수행 할 수 있습니다 : 그것은 그룹화 요인으로

titanic %>% 
    mutate(Pclass = as.factor(Pclass)) %>% 
    group_by(Pclass, Sex) %>% 
    mutate(Age.mean = mean(Age), 
     Age.sd = sd(Age), 
     outlier.max = Age.mean + Age.sd, 
     outlier.min = Age.mean - Age.sd, 
     outlier = as.factor(ifelse(Age > outlier.max, 1, 
            ifelse(Age < outlier.min, 1, 0)))) %>% 
    ggplot() + 
    geom_point(aes(Age, Pclass, colour = outlier)) + 
    facet_grid(.~Sex) 

Pclass는 미리 요인으로 변이된다. 그런 다음 두 개의 새로운 데이터 프레임을 만드는 대신 원본 데이터 프레임 내에서 단계가 완료됩니다. 그러나 원래 데이터 세트는 변경되지 않습니다! 이를 원하면 titanic 또는 다른 데이터 프레임에 결과를 다시 할당하고 다음 단계로 ggplot -part를 실행하십시오. 그렇지 않으면 그림의 결과를 데이터에 할당합니다.

아웃 라이어 식별을 위해 한 가지 방법은 ifelse으로 작업하는 것입니다. , 당신도 줄일 수 또한 :

... 
rowwise() %>% 
    mutate(outlier = as.factor(as.numeric(between(Age, outlier.min, outlier.max)))) %>% ... 

플러스 : 또는 dplyr 그러나이 들어, 이상치에 대한 최소 및 최대 임계 값을 생성 한 후 rowwise, 즉 추가해야합니다, 좋은 between 기능을 제공합니다

titanic %>% 
    group_by(Pclass, Sex) %>% 
    mutate(outlier = as.factor(ifelse(Age > (mean(Age) + sd(Age)), 1, 
             ifelse(Age < (mean(Age) - sd(Age)), 1, 0)))) %>% 
    ggplot() + 
    geom_point(aes(Age, as.factor(Pclass), colour = outlier)) + 
    facet_grid(.~Sex)