【问题标题】:R Create new variable based on group and multiple column conditionR根据组和多列条件创建新变量
【发布时间】:2020-12-06 00:44:53
【问题描述】:

有人可以帮我将 group_by 函数(或任何可以解决问题的函数)插入其中:

df$buy <-ifelse(
 ( 
 (df$month %in% c(201909, 201910,  201911, 201912, 202001, 202002)) &
  (df$activity== 0)                                  
  ),
  1,  
  0   
 )

我的数据包含三列:ID、月份和 X。每个 id 有 12-14 个观察值。我想按 id 分组,然后将 1 分配给组中的所有 ID,其中月份 = 201009、201919、201911、201912、202001、202002 和 X 在这些行中 = 0。 例如,buy 是我要创建的新变量:

 ID  MONTH  X Buy
 1   201901 1 1
 1   201002 0 1
 1   201903 1 1
 1   201904 0 1
 1   201905 1 1
 1   201906 1 1
 1   201907 0 1
 1   201908 0 1
 1   201909 0 1
 1   201910 0 1
 1   201911 0 1
 1   201912 0 1
 1   202001 0 1
 1   202002 0 1
 2   201901 1 0
 2   201902 1 0
 2   201903 0 0
 2   201904 0 0
 2   201905 0 0 
 2   201906 1 0 
 2   201907 0 0 
 2   201908 0 0 
 2   201909 0 0
 2   201910 1 0 
 2   201911 0 0 
 2   201912 1 0 
 2   202001 0 0 
 2   202002 0 0 

仅当上述月份在 X 列中为零时,我希望基于 ID 的整个组为 1,如果不符合要求则为零。提前谢谢你。

【问题讨论】:

  • 您的代码应该可以在不需要 group by 的情况下工作!
  • 如果 Duck 不正确,那么很可能是因为我们对输入数据和您的预期输出了解不够。请通过添加示例 unambiguous 数据(例如,data.frame(x=...,y=...) 或来自dput(head(x)) 的输出)和给定该输入的预期输出,使这个问题更具重现性。参考:stackoverflow.com/q/5963269minimal reproducible examplestackoverflow.com/tags/r/info
  • @r2evans 你是对的,我的要求并不清楚。我已经编辑了帖子以包含我的一些数据和我想要的结果。谢谢你们。

标签: r


【解决方案1】:

我认为这将达到您的目的

library(tidyverse)

df %>% filter(MONTH %in% c(201909, 201910,  201911, 201912, 202001, 202002)) %>%
  group_by(ID) %>% summarise(Buy = sum(X+1)) %>%
  mutate(Buy = ifelse(Buy == 6, 1, 0)) %>% right_join(df) %>%
  select(1, 3:4, 2)

   ID  MONTH X Buy
1   1 201901 1   1
2   1 201902 0   1
3   1 201903 1   1
4   1 201904 0   1
5   1 201905 1   1
6   1 201906 1   1
7   1 201907 0   1
8   1 201908 0   1
9   1 201909 0   1
10  1 201910 0   1
11  1 201911 0   1
12  1 201912 0   1
13  1 202001 0   1
14  1 202002 0   1
15  2 201901 1   0
16  2 201902 1   0
17  2 201903 0   0
18  2 201904 0   0
19  2 201905 0   0
20  2 201906 1   0
21  2 201907 0   0
22  2 201908 0   0
23  2 201909 0   0
24  2 201910 1   0
25  2 201911 0   0
26  2 201912 1   0
27  2 202001 0   0
28  2 202002 0   0

如果X 有负值,可能需要更改代码。

【讨论】:

    【解决方案2】:

    由于 TO 没有指定合适的示例,我创建了一个示例。

    一般来说,我想知道这一切是否可以更轻松地完成,但我突然想到,这可能是少数情况之一,首先使用 pivot_wider 来计算新变量是有意义的。所以这就是我正在做的:

    • 旋转范围更广,以便每个月都有自己的列,每个 ID 都是一行。
    • 对某些月份的列进行逐行计算,并检查其中是否至少有一个为 1。
    • 重新调整为长格式。

    注意:

    • 由于我创建了自己的数据框,因此我采取了一些捷径,因此这些值与 TO 示例不对应。
    • 我还只是使用了一些示例列进行行计算,再次与 TO 提供的列不匹配。
    • 但是,这一切都可以在下面的代码中轻松调整:

    创建数据

    set.seed(1)
    df <- data.frame(ID = c(rep(1:2, each = 12)),
                     MONTH = paste0(c(rep(2019, 12)), rep(1:12, 2)),
                     X = round(runif(24, 0,1),0))
    

    进行计算

    library(tidyverse)
    df %>%
      pivot_wider(id_cols      = ID,
                  names_from   = MONTH,
                  names_prefix = "MONTH_",
                  values_from  = X) %>%
      mutate(Buy = apply(across(c(MONTH_20191, MONTH_20195, MONTH_201912)), 1, function(x) (any(x == 1))),
             Buy = as.numeric(Buy)) %>%
      pivot_longer(cols = starts_with("MONTH"),
                   names_prefix = "MONTH_",
                   names_to = "MONTH",
                   values_to = "X") %>% print(n=Inf)
    

    结果

    # A tibble: 24 x 4
          ID   Buy MONTH      X
       <int> <dbl> <chr>  <dbl>
     1     1     0 20191      0
     2     1     0 20192      0
     3     1     0 20193      1
     4     1     0 20194      1
     5     1     0 20195      0
     6     1     0 20196      1
     7     1     0 20197      1
     8     1     0 20198      1
     9     1     0 20199      1
    10     1     0 201910     0
    11     1     0 201911     0
    12     1     0 201912     0
    13     2     1 20191      1
    14     2     1 20192      0
    15     2     1 20193      1
    16     2     1 20194      0
    17     2     1 20195      1
    18     2     1 20196      1
    19     2     1 20197      0
    20     2     1 20198      1
    21     2     1 20199      1
    22     2     1 201910     0
    23     2     1 201911     1
    24     2     1 201912     0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-03
      相关资源
      最近更新 更多