【问题标题】:How to filter data frame by a minimal difference by groups如何通过组的最小差异过滤数据框
【发布时间】:2021-11-19 11:17:31
【问题描述】:

我正在苦苦思考如何才能在我的数据框中只保留 measure 中的值差异对于 id1 中的每个组而言 2 最小的元素。这是一个玩具示例:

test = data.frame(measure = c(1, 2, 3, 2, 2, 4, 0, 1),
                  id1 = c("A", "B", "A", "B", "C", "C", "A", "D"),
                  id2 = c("16", "16", "16", "16", "17", "17", "17", "18"))
# > test
#   measure id1 id2
# 1       1   A  16
# 2       2   B  16
# 3       3   A  16
# 4       2   B  16
# 5       2   C  17
# 6       4   C  17
# 7       0   A  17
# 8       1   D  18

#as result, I'd like something like
#> res
#   measure id1 id2
# 1       1   A  16
# 3       3   A  16
# 5       2   C  17
# 6       4   C  17
# 7       0   A  17

id1 等于 AD 被删除,因为它们的 max(value) - min(value) < 2

关于如何应用它的任何提示?

【问题讨论】:

  • 是否也应该通过分组measure来完成删除?还是忽略measure 列?
  • @PaulSmith measure 列将用于计算最小值和最大值,group_by 应使用 id1
  • 类似:if(max(value) - min(value) >= 2 by each id1 我们保留它们

标签: r dataframe dplyr


【解决方案1】:

另一个tidyverse 选项。

test %>% 
  group_by(id1) %>% 
  filter((max(measure)- min(measure)) >= 2)

【讨论】:

  • 谢谢,@Quixotic22:我刚刚从你那里得知,这里可以不用c_across
【解决方案2】:

一个可能的解决方案:

library(tidyverse)

test = data.frame(measure = c(1, 2, 3, 2, 2, 4, 0, 1),
                  id1 = c("A", "B", "A", "B", "C", "C", "A", "D"),
                  id2 = c("16", "16", "16", "16", "17", "17", "17", "18"))

test %>% 
  group_by(id1) %>% 
  mutate(aux = (max(c_across(measure))- min(c_across(measure))) >= 2) %>% 
  ungroup %>% filter(aux) %>% select(-aux)

#> # A tibble: 5 × 3
#>   measure id1   id2  
#>     <dbl> <chr> <chr>
#> 1       1 A     16   
#> 2       3 A     16   
#> 3       2 C     17   
#> 4       4 C     17   
#> 5       0 A     17

【讨论】:

    【解决方案3】:

    data.table 结构在这里提供了一个选项。

    # Load library
    library(data.table)
    # Create data.table
    test <- 
      data.table(measure = c(1, 2, 3, 2, 2, 4, 0, 1),
                 id1 = c("A", "B", "A", "B", "C", "C", "A", "D"),
                 id2 = c("16", "16", "16", "16", "17", "17", "17", "18"))
    # Solution:
    test[id1 %in% test[, .(max(measure)-min(measure)), by=id1][V1>=2, id1]]
    

    在这个解决方案中,test[, .(max(measure)-min(measure)), by=id1] 给出了一个 data.table 的差异,[V1&gt;=2, id1] 对其进行子集化并返回一个有效 id1 值的向量。然后id1 %in% 将原始数据作为该向量内容的子集。

    结果是:

     measure id1 id2
    1:       1   A  16
    2:       3   A  16
    3:       2   C  17
    4:       4   C  17
    5:       0   A  17
    

    小型 data.table 课程:

    • 对于 data.tables,我们使用符号 DT[i, j, by] 其中:

      • DT 是数据表
      • i 是对观察的操作(例如过滤、排序)
      • j 是对变量的操作(例如选择、处理)
      • by(和keyby)为j-操作提供分组
    • data.tables 有一些特殊字符,包括

      • .N 表示“观察次数”
      • .SD 用于“选定变量”
    • 安装并加载 data.table 包以使用此结构。

    • 使用setDT()data.table() 将现有的data.frame、list 或tibble 转换为data.table

    • 使用fread() 将外部数据文件直接读入data.table。

    一个例子 - 从 mtcars 中获取汽车的数量和平均燃油效率,其中 hp>100 和按气缸数分组的汇总统计数据:

    dtcars <- data.table(mtcars)
    dtcars[hp>100, .("n" = .N, "mean_mpg" = mean(mpg)), keyby=cyl]
    

    【讨论】:

      猜你喜欢
      • 2018-04-04
      • 1970-01-01
      • 1970-01-01
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 2015-12-10
      • 1970-01-01
      • 2021-08-19
      相关资源
      最近更新 更多