2014-09-30 5 views
-1

데이터 유형이 서로 다른 약 40 열의 데이터 프레임이 있습니다. 처음 15 열 정도의 고유 한 색인 역할을하는 변수가 있습니다. 이 열은 병합 된 관계형 데이터베이스이므로이 인덱스 변수에서 동일한 값을 갖는 모든 행이 동일해야합니다. 그러나 그들은 그렇지 않습니다. 오타가있는 곳을 찾고 싶습니다. 나는이 아주 간단한 예를했습니다대략적으로 평평하게 된 데이터 프레임에서 오타 (요소로 인해 불규칙한 행)를 찾습니다. R

는 :

structure(list(f = structure(c(1L, 2L, 3L, 3L, 4L, 5L, 6L, 6L, 
7L, 7L), .Label = c("a", "b", "c", "d", "e", "f", "g"), class = "factor"), 
    number = c(1, 2, 3, 3, 4, 5, 6, 7, 21, 21), name = structure(c(1L, 
    2L, 4L, 3L, 5L, 6L, 7L, 7L, 8L, 8L), .Label = c("alfa", "beta", 
    "calostrE", "calostrO", "dedo", "elefante", "fiasco", "general" 
    ), class = "factor")), .Names = c("f", "number", "name"), row.names = c(NA, 
-10L), class = "data.frame") 

은 다음과 같습니다

f number  name 
1 a  1  alfa 
2 b  2  beta 
3 c  3 calostrO 
4 c  3 calostrE 
5 d  4  dedo 
6 e  5 elefante 
7 f  6 fiasco 
8 f  7 fiasco 
9 g  21 general 
10 g  21 general 

f는 고유 인덱스입니다. 원래 데이터 프레임에서는 요인으로 변환 된 날짜이지만 그 것은 부적절합니다. 보시다시피 행 9와 10은 다른 변수 값이 모두 동일하기 때문에 올바릅니다. 요소 값 당 하나의 행만 있기 때문에 행 1,2,5 및 6도 정확합니다. 그러나 행 쌍 3-4와 7-8은 올바르지 않습니다. 오타가 있으며 변수가 동일하지 않은 경우가 있습니다. 도 보시다시피

Rows.with.typos..........Column.names 
.....3......................."name" 
.....7......................."number" 

, 내가 인하에 문제가 :

내가 원하는 결과는 다음과 같은 것입니다.

이 예제는 간단하지만 둘 이상의 열에 부등식 (오타)이있는 경우 최종 결과에 "열 이름"아래에 둘 이상의 요소가 있어야합니다. 필자의 원래 데이터 프레임은 꽤 넓고 많은 수의 열을 가지고 있으며, 일부만 f의 주어진 값에 대해 행별로 동일해야합니다.

명확화 : 선택한 행은 항상 그룹의 첫 번째 항목입니다 (아래 의견에 대한 내 답변 참조).

필자는 오타가있는 행을 얻을 수 있었지만 매우 복잡한 방식으로 게시하는 것이 좋지 않을 것이라고 생각합니다.

+0

길모 7 행을 어떻게 잘못 선택했는지는 확실하지 않습니다. 숫자 나 이름 등에서 약간의 차이가있는 사람들의 첫 번째 행을 선택 하시겠습니까? – akrun

+0

한 가지 방법은'by' 또는'dplyr'의'group_by' ('f' 컬럼에 그룹화)를'split '한 다음 *를 통해 서로 다른 컬럼에 대해'any' /'duplicated'를 테스트하는 것입니다 적용 '을 클릭하고 해당 열 이름을 반환하십시오. – hrbrmstr

+1

또한 비교 대상은 무엇입니까? 각 그룹의 첫 번째 값은? 2 개가 동일하고 세 번째가 다른 그룹에서 두 개 이상의 값을 가진다면 어떤 일이 발생합니까? 어떤 것은 오타, 처음 두 개는 유사하거나 세 번째로 식별됩니까? –

답변

1

나 자신 트릭을 수행하는 함수를 만들었습니다. 더 나은 점은 다른 모든 셀에 선이 채워져 있기 때문에 오타가 쉽게 표시 될 수있는 다른 Excel 파일을 생성하기 때문입니다. 초보자 나 데이터 클리너에게는 유용 할 수 있지만 코드를 완벽하게 만들 수 있다고 생각합니다. 변수 및 함수 이름은 스페인어로되어 있습니다.

detectar_errores<-function(x,variables,index){ 

#The first argument is the dataframe. The third argument is the index. And the second is a vector, that can be numerical (positional) or of variable names, and specifies which variables are the ones that should have identical values if the variable "index" has the same values. 


#Checks packages 


if(require("xlsx")){ 
    print("xlsx está correctamente cargado") 
} else { 
    print("tratando de instalar xlsx") 
    install.packages("xlsx") 
    if(require(xlsx)){ 
     print("xlsx instalado y cargado") 
    } else { 
     stop("no pude instalar y cargar xlsx") 
    } 
} 

if(require("dplyr")){ 
    print("dplyr está correctamente cargado") 
} else { 
    print("tratando de instalar dplyr") 
    install.packages("dplyr") 
    if(require(dplyr)){ 
     print("dplyr instalado y cargado") 
    } else { 
     stop("no pude instalar y cargar dplyr") 
    } 
} 


#Selects the variables and groups by index 
#Then creates a new variable, that is TRUE is there is more than one row in the group and there are the same rows as unique index values 
#The result is stored in a new dataframe called "primera" 

primera<-x %>% select(variables) %>% group_by(index) %>% do({ 
    clasificador<-nrow(.)==nrow(unique(.)) & nrow(.)>1 
    data.frame(.,clasificador) #El punto es un símbolo para el grupo 
}) 

#Selects the rows that interest us and stores them in another dataframe 

segunda<-primera[primera$clasificador==T,] 

#Creates a function that takes a vector and checks if all its elements are identical(i.e: 3, 3, 3) 
#If they are, returns as many NAs as the vector length (that variables doesn't have typos) 
#If they aren't, returns the same vector, in order to the discrepancies to be seen 

todosiguales<-function(x){ 
    clase<-class(x) 
    if(identical(x,rep(x[1],length(x)))){ 
    solucion<-rep(NA,length(x)) 
    class(solucion)<-clase 
    return(solucion) 
    }else{ 
return(x)} 
} 

#Creates a function that substitutes the NAs for lines in a character vector 

rayas<-function (y){ 
    y[is.na(y)]<-"--" 
    return(y) 
} 

#Creates another dataframe by manipulating the previous one 
#It groups by the index and then transforms the variables 
#It coerces them to character, then applies the function todosiguales and then the funcion rayas 

tercera<-segunda %>% 
     group_by(index) %>% 
     mutate_each(funs(as.character)) %>% 
     mutate_each(funs(todosiguales)) %>% 
     mutate_each(funs(rayas)) 

#That returns the last dataframe. Now it's written as a new Excel file 

write.xlsx(tercera,"Errores_detectados.xls") 
} 
0

시도해 볼 수 있습니다. (df1은 데이터 세트입니다.) 두 그룹이 각각 f 그룹에 대해 세 개 이상일 때 비교가 어떻게 이루어져야하는지는 분명하지 않습니다.

df1$name <- as.character(df1$name) 
res <- do.call(rbind, lapply(split(df1[, -1], df1$f), function(x) { 
indx <- !(duplicated(x) | duplicated(x, fromLast = TRUE) | nrow(x) == 1) 
x1 <- x[indx] 
x2 <- x1[1, !apply(x1, 2, anyDuplicated) > 0] 
if (length(x1) > 0){ 
    data.frame(Rows.with.typos = rownames(x1)[1], 
      Column.names = x2, stringsAsFactors = FALSE)} 
})) 

res 
# Rows.with.typos Column.names 
#c    3  calostrO 
#f    7   6 
+1

rbind (deparse.level, ...)의 오류 : 인수 열 수가 일치하지 않습니다. –

0

숫자와 이름 열이 결합 된 경우 다음은 고유 항목 만 표시합니다. 오타는 명확하게 여기 볼 것입니다 :이 중복되기 때문에

> ddf[!duplicated(paste(ddf$number,ddf$name)),] 
    f number  name 
1 a  1  alfa 
2 b  2  beta 
3 c  3 calostrO 
4 c  3 calostrE 
5 d  4  dedo 
6 e  5 elefante 
7 f  6 fiasco 
8 f  7 fiasco 
9 g  21 general 

행 번호 (10)는 오지 않았다.

위에서 만 중복 사람을 보여줍니다 다음은

> ddf2 = ddf[!duplicated(paste(ddf$number,ddf$name)),] 
> ddf2[duplicated(ddf2$number) | duplicated(ddf2$name),] 
    f number  name 
4 c  3 calostrE 
8 f  7 fiasco 
+0

이 출력은 요청 된 출력이 아닙니다. –