2017-09-22 8 views
1

私の質問は、列の値と固定された数値の間で最も近い値を見つける代わりにthis oneとほぼ同じです。 "2"、私はの値に最も近い値を見つけたいと思います。df内の他の2つの列間で最も近い値を見つけることに基づく戻り値

df <- data.frame(site_no=c("01010500", "01010500", "01010500","02010500", "02010500", "02010500", "03010500", "03010500", "03010500"), 
        OBS=c(423.9969, 423.9969, 423.9969, 123, 123, 123, 150,150,150), 
        MOD=c(380,400,360,150,155,135,170,180,140), 
        HT=c(14,12,15,3,8,19,12,23,10)) 

次のようになります:

site_no  OBS MOD HT 
1 01010500 423.9969 380 14 
2 01010500 423.9969 400 12 
3 01010500 423.9969 360 15 
4 02010500 123.0000 150 3 
5 02010500 123.0000 155 8 
6 02010500 123.0000 135 19 
7 03010500 150.0000 170 12 
8 03010500 150.0000 180 23 
9 03010500 150.0000 140 10 

目標は、すべての「site_no」、OBS値に一致する最も近いMOD値を見つけるために、その後、返却され は、ここでデータの例です対応するHT。たとえば、site_no 01010500の場合、423.9969 - 400は最小の差を生み出し、したがって関数は12を返します。私は他のポストの解のほとんどを試しましたが、原子ベクトルを持つ$のためにエラーが発生します(dfは再帰的です、しかし、私はその機能がないと思う)。私が試した:

ddply(df, .(site_no), function(z) { 
    z[abs(z$OBS - z$MOD) == min(abs(z$OBS - z$MOD)), ] 
}) 
Error in z$River_Width..m. - z$chan_width : 
    non-numeric argument to binary operator 
+0

恐らく 'ライブラリ(dplyr); (ds%)%group_by(site_no)%>%スライス(which.min(abs(OBS-MOD)))df%>%group_by(site_no)%>%スライス(which.min(HT)) ' ' – akrun

+0

@akrun、第2オプションは素晴らしいです。あなたが1人として提出すれば、私はそれを答えとして受け入れることができます。唯一の質問:返されるstrは、揺れ、いくつかのデータフレームのtblのブロックです。私は単一のデータフレームでこの結果を得ることができますか? – LauraR

+0

ありがとうございます。私はいくつかの説明を加えて解決策としてコメントを追加しました。あなたはそれを必要ならばdata.frameに変換することができます – akrun

答えて

0

'site_no' によってグループ化した後、私たちは 'OBS' と 'MOD'

library(dplyr) 
res <- df %>% 
     group_by(site_no) %>% 
     slice(which.min(abs(OBS-MOD))) 

NOTE間の最小絶対差がある行slicedplyrを使用することにより、いくつかのほとんどの他の機能で動作するはずのtbl_dftibbleなどの追加クラスが追加されています。何か問題があれば、それをdata.frameに変換することができます。as.data.frame

str(res %>% 
     as.data.frame) 
#'data.frame': 3 obs. of 4 variables: 
#$ site_no: Factor w/ 3 levels "01010500","02010500",..: 1 2 3 
#$ OBS : num 424 123 150 
#$ MOD : num 400 135 140 
#$ HT  : num 12 19 10 
+0

これには1つのわずかな問題があります。ネクタイがある場合、演算子はインデックスの最初の値を返します。理想的には、私はそれが最大(HT)を返すようにしたいと思います。これをスライスを使用して動作させることはできません。フィルタリングとランク付けを試みましたが、そのような運はありませんでした。 – LauraR

+0

@LauraRその場合、 'df%>%group_by(site_no)%>%arrange(site_no、desc(HT))%>%スライス(which.min(abs(OBS-MOD))' 'df $ MOD [5] < - 135'を変更した後 – akrun

関連する問題