【问题标题】:R dplyr::Filter dataframe by group and numeric vector?R dplyr::按组和数字向量过滤数据帧?
【发布时间】:2020-02-18 09:39:53
【问题描述】:

我有数据框df1 包含数据和组,df2 存储相同的组,每个组一个值。

我想通过df2 过滤df1 的行,其中lag 按组高于指示值。

虚拟示例:

  # identify the first year of disturbance by lag by group
df1 <- data.frame(year = c(1:4, 1:4),
                 mort = c(5,16,40,4,5,6,10,108),
                 distance = rep(c("a", "b"), each = 4)) 


df2 = data.frame(distance = c("a", "b"),
                       my.median = c(12,1))

现在计算值之间的滞后(创建新列)并根据df2 的列值过滤df1

# calculate lag between years
df1 %>% 
  group_by(distance) %>% 
  dplyr::mutate(yearLag  = mort - lag(mort, default = 0)) %>% 
  filter(yearLag > df2$my.median)  ##

但这不会产生预期的结果:

# A tibble: 3 x 4
# Groups:   distance [2]
   year  mort distance yearLag
  <int> <dbl> <fct>      <dbl>
1     2    16 a             11
2     3    40 a             24
3     4   108 b             98

相反,我希望得到:

# A tibble: 3 x 4
# Groups:   distance [2]
   year  mort distance yearLag
  <int> <dbl> <fct>      <dbl>
1     3    40 a             24
2     1     5 b              5
3     3    10 b              4

filter 在应用于单个值时效果很好,但如何使其适应向量,尤其是组向量(因为元素的顺序可能会改变?)

【问题讨论】:

  • 为什么没有选中b组mort=108的行?
  • 正如您所指出的,您所做的过滤不会以行方式处理来自 df2 的 row.median,而是仅使用第一个值 (12)。因此,您应该遵循 Aron 的回答。

标签: r dataframe dplyr


【解决方案1】:

这是你想要做的吗?

df1 %>% 
  group_by(distance) %>% 
  dplyr::mutate(yearLag  = mort - lag(mort, default = 0)) %>% 
  left_join(df2) %>%
  filter(yearLag > my.median)

结果:

# A tibble: 4 x 5
# Groups:   distance [2]
   year  mort distance yearLag my.median
  <int> <dbl> <fct>      <dbl>     <dbl>
1     3    40 a             24        12
2     1     5 b              5         1
3     3    10 b              4         1
4     4   108 b             98         1

【讨论】:

    【解决方案2】:

    这是data.table 方法

    library( data.table )
    #creatae data.tables 
    setDT(df1);setDT(df2)
    #create yearLag variable
    df1[, yearLag := mort - shift( mort, type = "lag", fill = 0 ), by = .(distance) ]
    #update join and filter wanted rows
    df1[ df2, median.value := i.my.median, on = .(distance)][ yearLag > median.value, ][]
    
    #    year mort distance yearLag median.value
    # 1:    3   40        a      24           12
    # 2:    1    5        b       5            1
    # 3:    3   10        b       4            1
    # 4:    4  108        b      98            1
    

    【讨论】:

      【解决方案3】:

      得出了同样的结论。你应该 left_join 数据框。

      df1 %>% left_join(df2, by="distance") %>% 
        group_by(distance) %>% 
        dplyr::mutate(yearLag  = mort - lag(mort, default = 0)) %>% 
        filter(yearLag > my.median)
      
      # A tibble: 4 x 5
      # Groups:   distance [2]
         year  mort distance my.median yearLag
        <int> <dbl> <fct>        <dbl>   <dbl>
      1     3    40 a               12      24
      2     1     5 b                1       5
      3     3    10 b                1       4
      4     4   108 b                1      98
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-28
        • 1970-01-01
        • 2016-12-05
        • 2011-08-28
        • 1970-01-01
        • 2019-08-08
        • 2021-02-27
        • 2018-06-02
        相关资源
        最近更新 更多