【问题标题】:How can I do a conditional variable based on a ID and Year? R如何根据 ID 和年份做一个条件变量? R
【发布时间】:2021-06-02 16:14:33
【问题描述】:

我正在处理公司数据集,并试图了解它们何时关闭

所以我的数据集是这样的:

Year    ID      Open
2014    a1       Y
2015    a1       Y
2016    a1       Y
2017    a1       Y

2014    a2       Y
2015    a2       N
2016    a2       N
2017    a2       N

2014    a3       Y
2015    a3       N
2016    a3       Y
2017    a3       N

我想制作3个条件变量

如果它在 2014 年开业并在 2015 年关闭,则为 1,否则为 0 如果它在 2014 年开业并在 2016 年关闭,则为 1,否则为 0 如果它在 2014 年开业并在 2017 年关闭,则为 1,否则为 0

所以我想要的数据集是这样的:

Year    ID      Open   C15   C16  C17
2014    a1       Y      -     -    -
2015    a1       Y      0     0    0
2016    a1       Y      0     0    0
2017    a1       Y      0     0    0  #Because firm never closed

2014    a2       Y      -     -    -
2015    a2       N      1     0    0 #Firm def. closed in 2015
2016    a2       N      0     1    0 #Still closed
2017    a2       N      0     0    1 #Still closed

2014    a3       Y      -     -    -
2015    a3       N      1     0    0  #Firm closed this year 
2016    a3       Y      0     0    0  #Firm is open again
2017    a3       N      0     0    1  #Firm closed again 

数据框按 ID 分组,但我不知道如何以 2014 年为条件

【问题讨论】:

    标签: r dataframe if-statement dplyr tidyverse


    【解决方案1】:

    我们可以编写一个根据条件给出 1/0 值的函数。

    is_open <- function(Open, Year, y1, y2) {
      as.integer(Open[match(y1, Year)] %in% 'Y' & 
                 Open[match(y2, Year)] %in% 'N' & Year %in% y2)
    }
    

    并为每个ID 和每个Year 值调用它

    library(dplyr)
    df %>%
      group_by(ID) %>%
      mutate(C15 = is_open(Open, Year, 2014, 2015), 
             C16 = is_open(Open, Year, 2014, 2016), 
             C17 = is_open(Open, Year, 2014, 2017)) %>%
      ungroup
    
    #    Year ID    Open    C15   C16   C17
    #   <int> <chr> <chr> <int> <int> <int>
    # 1  2014 a1    Y         0     0     0
    # 2  2015 a1    Y         0     0     0
    # 3  2016 a1    Y         0     0     0
    # 4  2017 a1    Y         0     0     0
    # 5  2014 a2    Y         0     0     0
    # 6  2015 a2    N         1     0     0
    # 7  2016 a2    N         0     1     0
    # 8  2017 a2    N         0     0     1
    # 9  2014 a3    Y         0     0     0
    #10  2015 a3    N         1     0     0
    #11  2016 a3    Y         0     0     0
    #12  2017 a3    N         0     0     1
    

    如果数据中有很多年并且您不能手动调用is_open,我们可以使用map

    bind_cols(df, purrr::map_dfc(2015:2017, 
                 ~df %>% 
                    group_by(ID) %>% 
                    transmute(!!paste0('C', .x) := is_open(Open, Year, 2014, .x)) %>%
                    ungroup %>%
                    select(-ID)))
    

    数据

    df <- structure(list(Year = c(2014L, 2015L, 2016L, 2017L, 2014L, 2015L, 
    2016L, 2017L, 2014L, 2015L, 2016L, 2017L), ID = c("a1", "a1", 
    "a1", "a1", "a2", "a2", "a2", "a2", "a3", "a3", "a3", "a3"), 
        Open = c("Y", "Y", "Y", "Y", "Y", "N", "N", "N", "Y", "N", 
        "Y", "N")), class = "data.frame", row.names = c(NA, -12L))
    

    【讨论】:

    • 你好,我收到了这个错误:(&gt; Balances2&lt;-Balances2 %&gt;% + group_by(RUC) %&gt;% + mutate(C15_aps = is_open_aps(APS, Año, 2014, 2015)) %&gt;% + ungroup Error: Problem with mutate()` input C15_aps.x Input C15_aps can't be recycled to size 8. i Input C15_aps is @987654333 @.i 输入C15_aps 的大小必须为 8 或 1,而不是 0。i 第 2 组出现错误:RUC = 190000222001.`)
    • 我更新了答案,将我使用的数据从您的帖子中复制为dput。 1)您能否测试我的答案是否按预期适用于该数据? 2) 如果它确实适用于该样本数据但不适用于您的实际数据,您能否以同样的方式使用dput 提供您的数据或数据子集,以便我可以测试我的答案?
    • 您从我帖子中的数据中得到了同样的错误?这很奇怪,它对我有用,对这些数据没有任何问题。
    • 不,我的数据也有同样的错误。该示例有效,也许是因为在我的真实数据中有很多NA?
    • 好的...尝试更新的函数is_open 来处理NA 值。
    猜你喜欢
    • 1970-01-01
    • 2016-11-05
    • 2019-11-23
    • 1970-01-01
    • 1970-01-01
    • 2019-03-02
    • 1970-01-01
    • 2021-03-27
    • 2022-08-13
    相关资源
    最近更新 更多