返回值基于在df中查找其他两列之间的最接近值

时间:2017-09-22 15:11:13

标签: r dataframe match plyr

我的问题几乎与this one相同,只是找不到列值和固定数字之间的最接近值,例如: " 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

目标是,对于每个&#34; site_no&#34;,找到与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

1 个答案:

答案 0 :(得分:0)

按照&#39; site_no&#39;进行分组后,我们slice在&#39; OBS&#39;之间具有最小绝对差异的行。和&#39; MOD&#39;

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

注意:使用dplyr时,会添加一些其他类,例如tbl_df tibble等,这些类应与大多数其他功能一起使用。如果有任何问题,我们可以使用as.data.frame

将其转换为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