【问题标题】:Mutate based on conditions?根据条件变异?
【发布时间】:2021-06-14 11:00:09
【问题描述】:
df <- data.frame(x1 = c("a","a","a","a","b","b","b","b"),ind = c("O","O","C","C","O","O","O","O"), num = c(6,12,18,24,6,12,18,24))
set.seed(1)
df <- df[sample(nrow(df)),]


df2 <- df %>% group_by(x1) %>%
  arrange(x1,num) 
> df2
# A tibble: 8 x 3
# Groups:   x1 [2]
  x1    ind     num
  <fct> <fct> <dbl>
1 a     O         6
2 a     O        12
3 a     C        18
4 a     C        24
5 b     O         6
6 b     O        12
7 b     O        18
8 b     O        24

我想为此数据创建一些新列,第一个应该检查列x1 的每个唯一值,它应该取列num 的最小值,其中列ind 等于C。对于值a,这应该返回18。然后它再次执行此操作,但检查ind 何时等于O。如果它什么也没找到,那么它应该只返回 N/A。所以这两列应该是这样的结果:

  x1    ind     num min_O min_C
  <fct> <fct> <dbl> <dbl> <dbl>
1 a     O         6     6    18
2 a     O        12     6    18
3 a     C        18     6    18
4 a     C        24     6    18
5 b     O         6     6    NA
6 b     O        12     6    NA
7 b     O        18     6    NA
8 b     O        24     6    NA

我尝试了按x1ind 列进行分组的变体,但无法让它工作,因为如果它等于特定值,我想做一个最小值。我相信有一个简单的方法!

【问题讨论】:

    标签: r dplyr tidyr


    【解决方案1】:

    这看起来有点麻烦,但确实有效

    library(dplyr)
    library(tidyr)
    
    df2 %>% 
     group_by(x1, ind) %>% 
     pivot_wider(names_from = ind, values_from = num, values_fn = min, names_prefix = 'min_') %>% 
     left_join(df2, by = 'x1')
    
    # A tibble: 8 x 5
    # Groups:   x1 [2]
      x1    min_O min_C ind     num
      <chr> <dbl> <dbl> <chr> <dbl>
    1 a         6    18 O         6
    2 a         6    18 O        12
    3 a         6    18 C        18
    4 a         6    18 C        24
    5 b         6    NA O         6
    6 b         6    NA O        12
    7 b         6    NA O        18
    8 b         6    NA O        24
    

    【讨论】:

    • 谢谢,去看看。希望这将是我缺少的一个简单的解决方案,可以做到这一点。 R(如excel)中没有minif函数或其他东西吗?
    • 无论如何您都必须将其转换为宽格式
    • 为什么会这样?
    • 因为您需要将其概括为不仅仅是两个ind。如果您不转换为宽格式,则必须手动完成(请参阅其他答案),因此扩大规模将非常困难且耗时
    【解决方案2】:

    另一种可能是

    library(tidyr)
    library(dplyr)
    df %>%
      arrange(x1,num) %>% 
      group_by(x1) %>%
      mutate(min_C = min(num[ind == "C"]), 
             min_O = min(num[ind == "O"]),
             across(starts_with("min"), ~ ifelse(.x == Inf, NA_real_, .x)))
    

    返回

    # A tibble: 8 x 5
    # Groups:   x1 [2]
      x1    ind     num min_C min_O
      <chr> <chr> <dbl> <dbl> <dbl>
    1 a     O         6    18     6
    2 a     O        12    18     6
    3 a     C        18    18     6
    4 a     C        24    18     6
    5 b     O         6    NA     6
    6 b     O        12    NA     6
    7 b     O        18    NA     6
    8 b     O        24    NA     6
    

    但也会返回警告,因为b 组中没有C

    如果不使用across(...) 部分,NAs 将替换为Inf

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-17
      • 1970-01-01
      • 2023-03-21
      • 2019-08-24
      • 2021-03-10
      • 2020-12-09
      相关资源
      最近更新 更多