【问题标题】:Return rows in an R dataframe where there is the max for each group based on a condition根据条件返回 R 数据框中的行,其中每个组都有最大值
【发布时间】:2021-08-10 07:49:47
【问题描述】:

您好,我有一个包含 2 列的简单数据框

scenario    item   ROA
0 -10 0      A   6.0
0   0 10     A   2.1
0  10 20     A   3.0
0 -30 0      B   0.5
10 0  0      B   1.0

我需要创建一种方法来调节每个项目的场景(只有正面或负面)并返回 ROA 最大值所在的行

例如,如果我让 A 只使用正面的场景,而 B 只使用负面的场景,我应该得到

    scenario    item   ROA
     0  10 20     A   3.0
     0 -30 0      B   0.5

scenario列的值是字符串而不是数字,但是只有一个负号,所以如果它包含“-”号可以用条件来检查。

否定场景的条件是字符串中有一个负字符,肯定的条件是它没有。

在这里你可以创建一些示例数据

scenario    <- c("0 -10 0","0 0 10","0 10 20","0 -30 0","0 -30 0")
item <- c("A","A","A","B","B")
ROA <- c(6,2.1,3,0.5,1)

dfts <- data.frame(scenario=scenario, item=item, ROA=ROA )

感谢您的帮助

【问题讨论】:

  • 您说场景栏是字符串类型的,能否请您提供可重现的数据,以免造成混淆?您的物品存放条件在哪里?即哪些是积极的哪些是消极的,或者这些是硬编码的?
  • @AnilGoyal 我添加了更多信息和一些示例数据

标签: r dplyr


【解决方案1】:

这只是另一种方法: 我使用了来自基本 R 的 strsplit 函数,它根据 sep 参数拆分字符串,这里是单个空格 " "。此函数返回一个与x 长度相同的列表,其中列表的ith 元素是x[i] 的分隔元素。这里scenario 的每个元素的长度为1。然后我选择了第二个分隔元素并将其转换为数字类:

library(dplyr)
library(purrr)

dfts %>%
  filter(map2_lgl(scenario, item, ~ (.y == "A" & as.numeric(strsplit(.x, " ")[[1]][2]) > 0) |
                    (.y == "B" & as.numeric(strsplit(.x, " ")[[1]][2]) < 0)))

  scenario item ROA
1  0 10 20    A 3.0
2  0 -30 0    B 0.5

【讨论】:

    【解决方案2】:

    基本 R 选项

    subset(
      subset(
        dfts,
        (1 + grepl("-", scenario)) == match(item, c("A", "B"))
      ),
      ave(ROA, item, FUN = max) == ROA
    )
    

    给予

      scenario item ROA
    3  0 10 20    A 3.0
    4  0 -30 0    B 0.5
    

    【讨论】:

      【解决方案3】:

      你在找这个吗?

      library(dplyr)
      
      dfts %>%
        filter((!grepl('-', scenario) & item == 'A') | 
                 grepl('-', scenario) & item == 'B') %>%
        group_by(item) %>%
        slice(which.max(ROA)) %>%
        ungroup
      
      #  scenario item    ROA
      #  <chr>    <chr> <dbl>
      #1 0 10 20  A       3  
      #2 0 -30 0  B       0.5
      

      【讨论】:

        【解决方案4】:

        我们可以使用

        library(dplyr)
        library(stringr)
        dfts %>%
             filter(!str_detect(scenario, '-') & item == 'A'| 
                str_detect(scenario, '-') & item == 'B') %>% 
             group_by(item) %>% 
             slice_max(n = 1, order_by = ROA)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-11-30
          • 2021-11-04
          • 1970-01-01
          • 2019-10-02
          • 2020-12-23
          • 2021-09-18
          • 2021-12-28
          相关资源
          最近更新 更多