2016-06-03 2 views
1

R은 인수를 정수로 저장합니다. 따라서 동일한 기능을 사용할 때 서로 다른 레벨을 가진 두 요소가 같은 이름 인 경우이를 찾을 수 없습니다. 우리가 물체를 보면 FALSE함수의 동작이 "일치"인 경우

는하지만, 그들은

y[1,] 
portfolio_date   security 
10414  2000-10-31 Currency Euro (Fwd) 

x 
portfolio_date   security 
10414  2000-10-31 Currency Euro (Fwd) 

가 궁극적으로 내가 할 수 있기를 원하는 사용자에게 동일하게 표시

y <- structure(list(portfolio_date = structure(c(1L, 1L, 1L, 2L, 2L, 
2L), .Label = c("2000-10-31", "2001-04-30"), class = "factor"), 
security = structure(c(2L, 2L, 1L, 3L, 2L, 4L), .Label = c("Currency Australia (Fwd)", 
"Currency Euro (Fwd)", "Currency Japan (Fwd)", "Currency United Kingdom (Fwd)" 
), class = "factor")), .Names = c("portfolio_date", "security" 
), row.names = c(10414L, 10417L, 10424L, 21770L, 21771L, 21774L 
), class = "data.frame") 

x <- structure(list(portfolio_date = structure(1L, .Label = "2000-10-31", class = "factor"), 
security = structure(1L, .Label = "Currency Euro (Fwd)", class = "factor")), 
.Names = c("portfolio_date", "security"), row.names = 10414L, class = "data.frame") 

identical(y[1,], x) 

결과 : 여기

는 MWE입니다 다음과 같은 문자 :

apply(y, 1, identical, x) 
10414 10417 10424 21770 21771 21774 
TRUE TRUE FALSE FALSE FALSE FALSE 
which(apply(y, 1, identical, x)) 
1 2 

어떻게해야합니까? 감사.

+2

'동일 함 (물방울 (y [1,]), 물방울 (x))'아니면 아마도 all.equal (y [1,], x, check.attributes = F)' – user20650

+0

사용해 주셔서 감사합니다. 동일하지 않은 물방울은 여전히 ​​FALSE를 반환합니다. 또한, apply (y, 1, function (z) all.equal (z, x, check.attributes = F))에는 이상한 결과가 있습니다. – lilster

+1

열을 문자로 변환해야합니다. 여기에 한 줄에 밑줄을 붙인 해결책이 있습니다 : apply (apply (y, 2, as.character), 1, 동일, apply (x, 2, as.character)) – Dave2e

답변

1

비교, 요인을 실행하기 위해서 문자 개체로 변환해야합니다.

apply(apply(y, 2, as.character), 1, identical, apply(x, 2, as.character)) 

내부 루프 캐릭터 오브젝트 소스 및 대상 데이터 프레임의 각 열을 변환하여 외부 행 통해 루프를 적용한 적용 혼자베이스 R을 사용하여 해결책이다. x 데이터 프레임에 둘 이상의 행이 있으면 실제 동작이 예상 한 것과 다를 수 있습니다.

3

한 가지 옵션은 dplyrrowwise을 사용하여 행 단위로 확인하는 것입니다. 동시에 row.names를 비교해야하는 경우 두 열 모두에 id 열을 만들어야합니다. 그렇지 않으면 처음 두 행에 TRUE이 반환됩니다.

library(dplyr) 
x$id <- row.names(x) 
y$id <- row.names(y) 
rowwise(y) %>% do(check = isTRUE(all.equal(., x, check.attributes = F))) %>% data.frame 

    check 
1 TRUE 
2 FALSE 
3 FALSE 
4 FALSE 
5 FALSE 
6 FALSE 
1

'비교'패키지를 사용하십시오. 데이터

library(compare) 
result <- NULL 
for (i in 1:NROW(y)){ 
one <- compare(y[i,], x, dropLevels=T) 
two <- one$detailedResult[1]==T & one$detailedResult[2]==T 
result <- c(result, two) 
} 
as.character(result)#TRUE TRUE FALSE FALSE FALSE FALSE 
1

해결

영업에 등록한 예 용이 droplevels()을 사용하여 처리 될 수 OP 게시. 두 객체가 같은 방식으로 표시됩니다에도 불구하고,

str(y[1,]) 
#'data.frame': 1 obs. of 2 variables: 
#$ portfolio_date: Factor w/ 2 levels "2000-10-31","2001-04-30": 1 
#$ security  : Factor w/ 4 levels "Currency Australia (Fwd)",..: 2 

따라서 차이가 요인에 달려있다

str(x) 
#'data.frame': 1 obs. of 2 variables: 
#$ portfolio_date: Factor w/ 1 level "2000-10-31": 1 
#$ security  : Factor w/ 1 level "Currency Euro (Fwd)": 1 

반면 :

것은 우리가 처음 identical(y[1,], x) 반환 FALSE 왜 비교를 보자 OP 질문에 표시되어 있습니다.

여기는 기능 droplevels()이 유용한 곳입니다. 사용되지 않는 요인이 제거됩니다. 의 중복 요인 y[1,]droplevels()을 적용함으로써 얻을 : x도되지 않는 요소를 포함

identical(droplevels(y[1,]), x) 
#[1] TRUE 

경우도 droplevels()로 포장 할 필요가있다. 실제 데이터는 "MWE에 게시 된 데이터보다 더 복잡한 경우 작동하지 않을 수 있습니다 droplevels()를 사용

identical(droplevels(y[1,]), droplevels(x)) 
#[1] TRUE 

일반 솔루션

: 어떤 경우, 어떤 해를하지 않을 것이다 "라고 말했다. 이러한 상황은 예컨대, 상이한 인자 레벨로서 저장된 xy[1,]의 등가 엔트리를 포함 할 수있다.droplevels()이 실패하는 예제는이 대답의 끝에 데이터 섹션에 나와 있습니다.

다음 솔루션은 이러한 일반적인 상황을 효과적으로 처리 할 수있는 방법을 나타냅니다. OP에 게시 된 데이터뿐만 아니라 아래에 게시 된 데이터의보다 복잡한 경우에도 작동합니다.

먼저 각 행의 문자 만 포함하는 두 개의 보조 벡터가 만들어집니다. paste()를 사용하여 우리는 하나의 문자열로 각 행을 연결할 수 있습니다 : 항목이 원래 수준이 다른 요소로 저장하더라도 원래 data.frames의 행을 비교하기 쉽게 가능하게 이러한 벡터와

temp_x <- apply(x, 1, paste, collapse=",") 
temp_y <- apply(y, 1, paste, collapse=",") 

을, 및 번호 매기기.

우리는 모든 가능한 열 조합 어떤지 전 검사로서,이 때의 함수 identical()보다 적합한 %in% 연산자를 사용하여, 동일 행을 식별하고, 아닌 개별 쌍.

원하는 출력 빠르게 얻을 수있다 간단한 수정을

와없이 상기 루프 :

setNames(temp_y %in% temp_x, names(temp_y)) 
#10414 10417 10424 21770 21771 21774 
# TRUE TRUE FALSE FALSE FALSE FALSE 
which(temp_y %in% temp_x) 
#[1] 1 2 
y[temp_y %in% temp_x,] 
#  portfolio_date   security 
#10414  2000-10-31 Currency Euro (Fwd) 
#10417  2000-10-31 Currency Euro (Fwd) 

데이터

x <- structure(list(portfolio_date = structure(1:2, .Label = c("2000-05-15", 
      "2000-10-31"), class = "factor"), security = structure(c(2L, 1L), 
      .Label = c("Currency Euro (Fwd)", "Currency USD (Fwd)"), 
      class = "factor")), .Names = c("portfolio_date", "security"), 
      class = "data.frame", row.names = c("10234", "10414")) 

y <- structure(list(portfolio_date = structure(c(1L, 1L, 1L, 2L, 2L, 2L), 
       .Label = c("2000-10-31", "2001-04-30"), class = "factor"), 
       security = structure(c(2L, 2L, 1L, 3L, 2L, 4L), 
       .Label = c("Currency Australia (Fwd)", "Currency Euro (Fwd)", 
       "Currency Japan (Fwd)", "Currency United Kingdom (Fwd)"), 
       class = "factor")), .Names = c("portfolio_date", "security"), 
       row.names = c(10414L, 10417L, 10424L, 21770L, 21771L, 21774L), 
       class = "data.frame") 
관련 문제