2016-10-21 3 views
-1

숫자 값을 기준으로 병합하려는 두 데이터 프레임이 있지만 부동 소수점 정확도에 문제가 있습니다. 아래의 예를 들어 두 data.frames을 가지고 : 값 (0.12 및 0.15)의 일부 인해 discussed in this post로 포인트 정확도 문제를 부동 일치하지 않는all.equal와 병합

> df1 <- data.frame(number = 0.1 + seq(0.01,0.1,0.01), letters = letters[1:10]) 
> df2 <- data.frame(number = seq(0.11,0.2,0.01), LETTERS = LETTERS[1:10]) 
> (merged <- merge(df1, df2, by = "number", all = TRUE)) 
    number letters LETTERS 
1 0.11  a  A 
2 0.12 <NA>  B 
3 0.12  b <NA> 
4 0.13  c  C 
5 0.14  d  D 
6 0.15 <NA>  E 
7 0.15  e <NA> 
8 0.16  f  F 
9 0.17  g  G 
10 0.18  h  H 
11 0.19  i  I 
12 0.20  j  J 

. 동등성을 찾는 해결책은 all.equal 함수를 사용하여 부동 소수점 아티팩트를 제거하는 것이지만 merge 함수 내에서이를 수행 할 방법이 없다고 생각합니다. 지금은 number 열 중 하나를 문자로 강제로 가져 와서 병합 후 숫자로 다시 되돌려 놓고 그 주위를 돌아 다니고 있습니다. 그러나 이것은 조금 어수선합니다.

> df1c <- df1 
> df1c[["number"]] <- as.character(df1c[["number"]]) 
> merged2 <- merge(df1c, df2, by = "number", all = TRUE) 
> merged2[["number"]] <- as.numeric(merged2[["number"]]) 
> merged2 
    number letters LETTERS 
1 0.11  a  A 
2 0.12  b  B 
3 0.13  c  C 
4 0.14  d  D 
5 0.15  e  E 
6 0.16  f  F 
7 0.17  g  G 
8 0.18  h  H 
9 0.19  i  I 
10 0.20  j  J 

누구든지이 문제에 대해 더 좋은 해결책이 있습니까?

감사합니다! 나는 다른 사람의 문제에 더 적용하기 위해 일반적으로 내 질문을 유지하고 싶은 데이터

에 대해 조금 더,하지만 내가 답을 얻기 위해 더 구체적으로해야 할 것 같다

편집 할 수 있습니다.

병합에 관련된 모든 문제는 부동 소수점 부정확으로 인한 것일 수 있지만 확실치 않을 수 있습니다. 데이터는 일련의 시계열 값, 시작 시간 및 빈도로 제공됩니다. 그런 다음 시계열 (ts) 개체로 바뀌고 많은 기능이 데이터 프레임으로 반환되는 시계열 (그 중 하나는 time 값)에서 기능을 추출하기 위해 호출됩니다. 한편 다른 일련의 함수가 시계열의 다른 기능을 목표로 가져 오기 위해 호출되고 있습니다. 원래의 시리즈를 보완하기 위해 생성 된 다른 시리즈의 잠재적 인 기능도 있습니다. 이 값들은 time 값을 사용하여 재결합되어야합니다.

이러한 각 프로세스 (피쳐 추출, 대상 계산, 병합)는 독립적으로 발생할 수 있어야하며 다른 플랫폼으로 전달 될 수 있도록 CSV 형식 형식으로 저장 될 수 있어야합니다. POSIXct 값으로 저장하는 것은 시리즈가 반드시 달력 시간에 저장되지 않으므로 어렵습니다.

+1

이것은 키로 절대 값을 사용하지 않는 이유입니다 ... 워크 플로우를 변경할 수 있는지 확인하십시오. 그러나 그 동안에 dplyr의 가입 패밀리를 사용해 보셨습니까? 예를 들어'dplyr :: full_join (df1c, df2, by = "number")'등이 있습니다. –

+0

병합 할 숫자 값은 시계열의 'time'값에서 가져온 것이고 문자 또는 요소로 변환됩니다. 숫자에는 고유 한 어려움이 있습니다. 또한'dplyr :: full_join()'도 작동하지 않습니다. 'df1c'를 사용하여'number'를'df1'보다는 문자로 변환했습니다. – Barker

+0

숫자로 변환하는 날짜/시간 필드에 직접 참여하지 않는 이유는 무엇입니까? –

답변

0

숫자를 동일하게 허용하는 정밀도 수준으로 반올림합니다. 당신은 정밀도 수준을 선택해야하는 경우

> df1$number=round(df1$number,2) 
> df2$number=round(df2$number,2) 
> 
> (merged <- merge(df1, df2, by = "number", all = TRUE)) 
    number letters LETTERS 
1 0.11  a  A 
2 0.12  b  B 
3 0.13  c  C 
4 0.14  d  D 
5 0.15  e  E 
6 0.16  f  F 
7 0.17  g  G 
8 0.18  h  H 
9 0.19  i  I 
10 0.20  j  J 

프로그래밍 당신은 우리에게 데이터에 대한 자세한 내용을 얘기해야하고 우리는 아마도이 때문에 항상 부동 소수점 부정확성에있을 것이라고 가정 할 수 있는지 여부. 그렇다면 소수점 이하 10 자리로 반올림하는 것이 좋습니다. all.equal 함수는 sqrt (.Machine $ double.eps)를 사용하는데, 보통 연습은 round(..., 16)과 유사해야합니다.

+0

위의 정보를 더 추가했습니다. 고맙습니다. – Barker