【问题标题】:Sub-setting by group closest to defined value按最接近定义值的组进行子设置
【发布时间】:2016-03-22 16:36:48
【问题描述】:

我有一个数据框,我想在每个组中选择y 最接近特定值的行(例如:5)。

set.seed(1234)
df <- data.frame(x = c(rep("A", 4),
                       rep("B", 4)),
                 y = c(rep(4, 2), rep(1, 2), rep(6, 2), rep(3, 2)),
                 z = rnorm(8))

df

##   x y          z
## 1 A 4 -1.2070657
## 2 A 4  0.2774292
## 3 A 1  1.0844412
## 4 A 1 -2.3456977
## 5 B 6  0.4291247
## 6 B 6  0.5060559
## 7 B 3 -0.5747400
## 8 B 3 -0.5466319

结果是:

##   x y          z
## 1 A 4 -1.2070657
## 2 A 4  0.2774292
## 3 B 6  0.4291247
## 4 B 6  0.5060559

谢谢你,菲利普

【问题讨论】:

    标签: r dplyr subset


    【解决方案1】:
    df %>%
      group_by(x) %>%
      mutate(
        delta = abs(y - 5)
      ) %>%
      filter(delta == min(delta)) %>%
      select(-delta)
    

    【讨论】:

      【解决方案2】:

      或者使用基础 R:

       df[do.call(c, tapply(df$y, df$x, function(x) x-5 == max(x - 5))),]
        x y          z
      1 A 4 -1.2070657
      2 A 4  0.2774292
      5 B 6  0.4291247
      6 B 6  0.5060559
      

      【讨论】:

        【解决方案3】:

        这是data.table 的选项。将'data.frame'转换为'data.table'(setDT(df)),按'x'分组,我们创建得到'y'与5的绝对差,从差中检查min的元素,获取行索引(.I),提取作为行索引的列(“V1”)并子集数据集。

        library(data.table)
        setDT(df)[df[, {v1 <- abs(y-5)
                       .I[v1==min(v1)]}, x]$V1]
        #   x y          z
        #1: A 4 -1.2070657
        #2: A 4  0.2774292
        #3: B 6  0.4291247
        #4: B 6  0.5060559
        

        【讨论】:

          【解决方案4】:
          val <- 5
          delta <- abs(val - df$y)
          df <- df[delta == min(delta), ]
          

          【讨论】:

          • 你不需要指定列
          • 添加这个不会使用x上的分组
          • 我指定 cols 是因为我不希望 diff 列包含在输出数据帧中,因为它实际上不应该是它的一部分。
          • 您可以将差异保持为数据帧的矢量输出
          猜你喜欢
          • 2015-10-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多