【问题标题】:How to subset identical rows from dataframe by condition in R?如何在 R 中按条件从数据框中子集相同的行?
【发布时间】:2022-08-21 18:51:03
【问题描述】:

从这个数据框中,我想对具有相同 \"model\"、\"Country\" 和 \"year\" 值但不同 \"factor\" 的行进行子集化

model <- c(\"A\",\"B\",\"C\",\"A\",\"A\",\"C\",\"B\",\"A\")
country <- c(\"Italy\",\"Germany\",\"Norway\",\"Italy\",\"France\",\"Germany\",\"Norway\",\"Italy\")
year <- c(2016,2016,2016,2016,2015,2015,2015,2015)
value <-  c(14,24,11,34,73,11,33,22)
factor <- c(\"NEW\",\"OLD\",\"OLD\",\"OLD\",\"OLD\",\"OLD\",\"NEW\",\"NEW\")

df <- data.frame(model,country,year,value, factor)

  model country year value factor
1     A   Italy 2016    14    NEW
2     B Germany 2016    24    OLD
3     C  Norway 2016    11    OLD
4     A   Italy 2016    34    OLD
5     A  France 2015    73    OLD
6     C Germany 2015    11    OLD
7     B  Norway 2015    33    NEW
8     A   Italy 2015    22    NEW

预期输出:

1     A   Italy 2016    22    NEW
4     A   Italy 2016    34    OLD
  • 第 1 行的输出不应该是 14 而不是 22?

标签: dataframe loops for-loop dplyr tidyverse


【解决方案1】:

你可以做的是创建一个列,根据组(型号、国家和年份)告诉重复的数量,然后 filter 如下所示:

model <- c("A","B","C","A","A","C","B","A")
country <- c("Italy","Germany","Norway","Italy","France","Germany","Norway","Italy")
year <- c(2016,2016,2016,2016,2015,2015,2015,2015)
value <-  c(14,24,11,34,73,11,33,22)
factor <- c("NEW","OLD","OLD","OLD","OLD","OLD","NEW","NEW")

df <- data.frame(model,country,year,value, factor)

library(dplyr)

df %>% 
  group_by(model, country, year) %>% 
  mutate(number_dups = n()) %>% 
  filter(number_dups > 1) %>%
  select(-number_dups) %>%
  ungroup()
#> # A tibble: 2 × 5
#>   model country  year value factor
#>   <chr> <chr>   <dbl> <dbl> <chr> 
#> 1 A     Italy    2016    14 NEW   
#> 2 A     Italy    2016    34 OLD

reprex package (v2.0.1) 于 2022 年 8 月 12 日创建

请注意:我假设预期的输出应该是 14 而不是 22。

【讨论】:

    【解决方案2】:

    在基础 R 中,您可以使用 subset + ave

    > subset(df, ave(seq_along(year), model, country, year, FUN = length) > 1)
      model country year value factor
    1     A   Italy 2016    14    NEW
    4     A   Italy 2016    34    OLD
    

    或者,试试Filter + split

    > Filter(function(x) nrow(x) > 1, split(df, ~ model + country + year))
    $A.Italy.2016
      model country year value factor
    1     A   Italy 2016    14    NEW
    4     A   Italy 2016    34    OLD
    

    或者

    > do.call(rbind, unname(Filter(function(x) nrow(x) > 1, split(df, ~ model + country + year))))
      model country year value factor
    1     A   Italy 2016    14    NEW
    4     A   Italy 2016    34    OLD
    

    【讨论】:

      【解决方案3】:

      您可以按modelcountryyear 进行分组,然后使用filter 保留具有modelcountryyear 重复值的行。然后,为了确保有不同的因子值,我们使用n_distinct 来确保factor 中至少有2 个不同的值(即,该组必须有NEWOLD)。

      library(dplyr)
          
      df %>%
        group_by(model, country, year) %>%
        filter(n() > 1 & n_distinct(factor) > 1)
      

      输出

        model country  year value factor
        <chr> <chr>   <dbl> <dbl> <chr> 
      1 A     Italy    2016    14 NEW   
      2 A     Italy    2016    34 OLD 
      

      附加示例:每组中的多个因素

      如果您只想在每个组中保留 1 行不同的因子(即 NEWOLD),那么我们可以添加 factor 作为附加分组变量并使用 slice 仅保留第一行每组。

      df2 <- structure(list(model = c("A", "B", "C", "A", "A", "C", "B", "A"
      ), country = c("Italy", "Germany", "Norway", "Italy", "France", 
      "Germany", "Norway", "Italy"), year = c(2016, 2016, 2016, 2016, 
      2015, 2015, 2015, 2016), value = c(14, 34, 11, 34, 33, 11, 33, 
      22), factor = c("NEW", "OLD", "OLD", "OLD", "OLD", "OLD", "NEW", 
      "NEW")), class = "data.frame", row.names = c(NA, -8L))
      
      #  model country year value factor
      #1     A   Italy 2016    14    NEW
      #2     B Germany 2016    34    OLD
      #3     C  Norway 2016    11    OLD
      #4     A   Italy 2016    34    OLD
      #5     A  France 2015    33    OLD
      #6     C Germany 2015    11    OLD
      #7     B  Norway 2015    33    NEW
      #8     A   Italy 2016    22    NEW
      
      df2 %>%
        group_by(model, country, year) %>%
        filter(n() > 1 & n_distinct(factor) > 1) %>%
        group_by(factor, .add = T) %>%
        slice(1) 
      

      输出

        model country  year value factor
        <chr> <chr>   <dbl> <dbl> <chr> 
      1 A     Italy    2016    14 NEW   
      2 A     Italy    2016    34 OLD   
      

      【讨论】:

        猜你喜欢
        • 2019-04-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-04
        • 2021-05-29
        • 2022-08-18
        • 1970-01-01
        相关资源
        最近更新 更多