2016-10-21 6 views
-1

私は数値に基づいてマージしたい2つのデータフレームを持っていますが、浮動小数点精度に問題があります。以下の例ように、2つの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列の1つを文字に強制し、マージ後に数値に戻すことで回避していますが、これはちょっとしたものです。

> 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 

誰でもこの問題の解決策がありますか?

ありがとうございます!

EDIT:データ

についてもう少し私は他の人の問題に対してより適用可能にするために、一般的な私の質問を維持したいが、私は答えを得るために、より具体的である必要がありそうです。

マージする際の問題は浮動小数点の不正確さに起因する可能性がありますが、確かめるのは少し難しいかもしれません。データは、一連の時系列値、開始時間、および周波数として取り込まれます。これらは時系列(ts)オブジェクトに変換され、多くの関数が呼び出されて時系列(そのうちの1つは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

関連する問題