【问题标题】:R - Create Row for Each Year of a Record based on column subtractionR - 根据列减法为记录的每一年创建行
【发布时间】:2021-12-29 00:46:58
【问题描述】:

我在志愿服务的 R 中有一个数据框。我想为志愿服务的每个财政年度设置一行。所以我的数据是这样进来的:

ID  Volunteership   FYStart FYEnd
1   Fabulousness    2019    2021
2   Graciousness    2021    2021
3   Loveliness  1995    1999

我需要为所涉及的每个会计年度创建一个新行,并且需要一个标记每个会计年度的“VolFY”列。我需要结束:

ID  Volunteership   FYStart FYEnd   VolFY
1   Fabulousness    2019    2021    2019
1   Fabulousness    2019    2021    2020
1   Fabulousness    2019    2021    2021
2   Graciousness    2021    2021    2021
3   Loveliness  1995    1999    1995
3   Loveliness  1995    1999    1996
3   Loveliness  1995    1999    1997
3   Loveliness  1995    1999    1998
3   Loveliness  1995    1999    1999

到目前为止,我玩过seq()rep()。我也玩过for 循环和while 循环,但还没有完全掌握正确的技巧。

如果你做过这种事情,请分享你是如何做到的。这是一个难题。

--玛丽安

【问题讨论】:

    标签: r loops seq


    【解决方案1】:

    这是tidyverse 中的一种方法-

    library(tidyverse)
    
    df %>%
      mutate(VolFY = map2(FYStart, FYEnd, seq)) %>%
      unnest(VolFY)
    
    #     ID Volunteership FYStart FYEnd VolFY
    #  <int> <chr>           <int> <int> <int>
    #1     1 Fabulousness     2019  2021  2019
    #2     1 Fabulousness     2019  2021  2020
    #3     1 Fabulousness     2019  2021  2021
    #4     2 Graciousness     2021  2021  2021
    #5     3 Loveliness       1995  1999  1995
    #6     3 Loveliness       1995  1999  1996
    #7     3 Loveliness       1995  1999  1997
    #8     3 Loveliness       1995  1999  1998
    #9     3 Loveliness       1995  1999  1999
    

    【讨论】:

    • 这成功了!谢谢。
    【解决方案2】:

    试试这个:

    newdat <- do.call(rbind, Map(function(ID, S, E) data.frame(ID=ID, VolFY=seq(S, E)), dat$ID, dat$FYStart, dat$FYEnd))
    merge(dat, newdat, by = "ID")
    #   ID Volunteership FYStart FYEnd VolFY
    # 1  1  Fabulousness    2019  2021  2019
    # 2  1  Fabulousness    2019  2021  2020
    # 3  1  Fabulousness    2019  2021  2021
    # 4  2  Graciousness    2021  2021  2021
    # 5  3    Loveliness    1995  1999  1995
    # 6  3    Loveliness    1995  1999  1996
    # 7  3    Loveliness    1995  1999  1997
    # 8  3    Loveliness    1995  1999  1998
    # 9  3    Loveliness    1995  1999  1999
    

    之所以可行,是因为我们首先遍历每一行并生成一个仅包含新年的迷你帧(在merge返回原始数据之前):

    Map(function(ID, S, E) data.frame(ID=ID, VolFY=seq(S, E)), dat$ID, dat$FYStart, dat$FYEnd)
    # [[1]]
    #   ID VolFY
    # 1  1  2019
    # 2  1  2020
    # 3  1  2021
    # [[2]]
    #   ID VolFY
    # 1  2  2021
    # [[3]]
    #   ID VolFY
    # 1  3  1995
    # 2  3  1996
    # 3  3  1997
    # 4  3  1998
    # 5  3  1999
    

    数据

    dat <- structure(list(ID = 1:3, Volunteership = c("Fabulousness", "Graciousness", "Loveliness"), FYStart = c(2019L, 2021L, 1995L), FYEnd = c(2021L, 2021L, 1999L)), class = "data.frame", row.names = c(NA, -3L))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多