为缺少的年份添加值为“ 0”的行

时间:2019-03-15 01:15:27

标签: r loops dataframe dplyr tidy

我有一个问题与发布的其他问题有点类似,但是在仔细查看了几篇文章之后,我无法使代码正常工作。任何帮助将不胜感激。

我的数据框如下所示:

'data.frame':   501 obs. of  5 variables:
 $ Tattoo.MUM   : Factor w/ 250 levels "1004","1007",..: 76 76 76 81 81 81 85 85 85 85 ...
 $ OffspringMUMs: int  4 4 4 4 4 4 11 11 11 11 ...
 $ YearBIRTH.CUB: int  1988 1990 1991 1988 1991 2007 1989 1991 1992 1993 ...
 $ YearBIRTH.MUM: int  1991 1991 NA NA NA NA 1987 1987 1987 1987 ...
 $ OFFSpYR      : int  2 1 1 1 2 1 1 4 3 3 ...

这里几行:

structure(list(Tattoo.MUM = structure(c(6L, 6L, 6L, 6L, 7L, 7L, 
7L, 8L, 9L, 11L, 11L, 11L, 11L, 5L, 1L, 4L, 2L, 3L, 3L, 10L, 
10L, 10L, 10L, 10L), .Label = c("10454", "1045A", "1045X", "12392", 
"1601", "22", "27", "29", "41", "424X", "60"), class = "factor"), 
OffspringMUMs = c(11L, 11L, 11L, 11L, 5L, 5L, 5L, 1L, 3L, 
7L, 7L, 7L, 7L, 1L, 2L, 1L, 1L, 4L, 4L, 6L, 6L, 6L, 6L, 6L
), YearBIRTH.CUB = c(1989L, 1991L, 1992L, 1993L, 1990L, 1991L, 
1993L, 1989L, 1988L, 1988L, 1989L, 1991L, 1994L, 2015L, 2012L, 
2015L, 2005L, 2009L, 2010L, 1996L, 1998L, 2000L, 2001L, 2006L
), YearBIRTH.MUM = c(1987L, 1987L, 1987L, 1987L, NA, NA, 
NA, NA, NA, 1987L, 1987L, 1987L, 1987L, NA, NA, NA, NA, 2005L, 
2005L, 1994L, 1994L, 1994L, 1994L, 1994L), OFFSpYR = c(1L, 
4L, 3L, 3L, 1L, 1L, 3L, 1L, 3L, 3L, 1L, 2L, 1L, 1L, 2L, 1L, 
1L, 2L, 2L, 1L, 1L, 1L, 2L, 1L)), .Names = c("Tattoo.MUM", 
"OffspringMUMs", "YearBIRTH.CUB", "YearBIRTH.MUM", "OFFSpYR"), class = "data.frame", row.names = c(NA, 
-24L))

我想在Tattoo.MUM中为所有缺少的年份(YearBIRTH.CUB)添加新行,保持其余值不变,并向OFFSpYR添加'0'。

像这样:

structure(list(Tattoo.MUM = structure(c(6L, 6L, 6L, 6L, 6L, 7L, 
7L, 7L, 7L, 8L, 9L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 5L, 1L, 
4L, 2L, 3L, 3L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 
10L, 10L), .Label = c("10454", "1045A", "1045X", "12392", "1601", 
"22", "27", "29", "41", "424X", "60"), class = "factor"), OffspringMUMs = c(11L, 
11L, 11L, 11L, 11L, 5L, 5L, 5L, 5L, 1L, 3L, 7L, 7L, 7L, 7L, 7L, 
7L, 7L, 1L, 2L, 1L, 1L, 4L, 4L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 
6L, 6L, 6L), YearBIRTH.CUB = c(1989L, 1990L, 1991L, 1992L, 1993L, 
1990L, 1991L, 1992L, 1993L, 1989L, 1988L, 1988L, 1989L, 1990L, 
1991L, 1992L, 1993L, 1994L, 2015L, 2012L, 2015L, 2005L, 2009L, 
2010L, 1996L, 1997L, 1998L, 1999L, 2000L, 2001L, 2002L, 2003L, 
2004L, 2005L, 2006L), YearBIRTH.MUM = c(1987L, 1987L, 1987L, 
1987L, 1987L, NA, NA, NA, NA, NA, NA, 1987L, 1987L, 1987L, 1987L, 
1987L, 1987L, 1987L, NA, NA, NA, NA, 2005L, 2005L, 1994L, 1994L, 
1994L, 1994L, 1994L, 1994L, 1994L, 1994L, 1994L, 1994L, 1994L
), OFFSpYR = c(1L, 0L, 4L, 3L, 3L, 1L, 1L, 0L, 3L, 1L, 3L, 3L, 
1L, 0L, 2L, 0L, 0L, 1L, 1L, 2L, 1L, 1L, 2L, 2L, 1L, 0L, 1L, 0L, 
1L, 2L, 0L, 0L, 0L, 0L, 1L)), .Names = c("Tattoo.MUM", "OffspringMUMs", 
"YearBIRTH.CUB", "YearBIRTH.MUM", "OFFSpYR"), class = "data.frame", row.names = c(NA, 
-35L))

我尝试过:

 library(tidyr)
 library(dplyr)

 df1 <- pedMUM %>% group_by(Tattoo.MUM, OffspringMUMs) %>% complete(YearBIRTH.CUB = full_seq(YearBIRTH.CUB,1)) %>% fill(OFFSpYR=0)

library(data.table)

df1 <- setDT(pedMUM)[CJ(Tattoo.MUM=Tattoo.MUM, OffspringMUMs=OffspringMUMs, YearBIRTH.MUM=YearBIRTH.MUM, YearBIRTH.CUB=seq(min(YearBIRTH.CUB), max(YearBIRTH.CUB)), unique=TRUE),
                 on=.(Tattoo.MUM, OffspringMUMs, YearBIRTH.CUB),  roll=T]

我显然错误地使用了tidyr,dplyr和data.table,因为没有人给我想要的结果。

我看过以下帖子:

Add rows with missing years by group

Adding rows with values of "0" to a dataframe with missing data

Find missing month after grouping with dplyr

甚至尝试循环:

R code - clever loop to add rows

但是当我尝试确定循环中每个Tattoo.MUM的年份顺序时,我会感到困惑。

有人能指出我正确的方向吗?

1 个答案:

答案 0 :(得分:1)

我以前没有使用过complete(),但是以下方法似乎可行。 nesting()允许您将两个变量保持在一起,=full_seq()允许您扩展变量的值,fill=list()允许您填充空格。

pedMUM <- structure(list(Tattoo.MUM = structure(c(6L, 6L, 6L, 6L, 7L, 7L,
7L, 8L, 9L, 11L, 11L, 11L, 11L, 5L, 1L, 4L, 2L, 3L, 3L, 10L,
10L, 10L, 10L, 10L), .Label = c("10454", "1045A", "1045X", "12392",
"1601", "22", "27", "29", "41", "424X", "60"), class = "factor"),
OffspringMUMs = c(11L, 11L, 11L, 11L, 5L, 5L, 5L, 1L, 3L,
7L, 7L, 7L, 7L, 1L, 2L, 1L, 1L, 4L, 4L, 6L, 6L, 6L, 6L, 6L
), YearBIRTH.CUB = c(1989L, 1991L, 1992L, 1993L, 1990L, 1991L,
1993L, 1989L, 1988L, 1988L, 1989L, 1991L, 1994L, 2015L, 2012L,
2015L, 2005L, 2009L, 2010L, 1996L, 1998L, 2000L, 2001L, 2006L
), YearBIRTH.MUM = c(1987L, 1987L, 1987L, 1987L, NA, NA,
NA, NA, NA, 1987L, 1987L, 1987L, 1987L, NA, NA, NA, NA, 2005L,
2005L, 1994L, 1994L, 1994L, 1994L, 1994L), OFFSpYR = c(1L,
4L, 3L, 3L, 1L, 1L, 3L, 1L, 3L, 3L, 1L, 2L, 1L, 1L, 2L, 1L,
1L, 2L, 2L, 1L, 1L, 1L, 2L, 1L)), .Names = c("Tattoo.MUM",
"OffspringMUMs", "YearBIRTH.CUB", "YearBIRTH.MUM", "OFFSpYR"), class = "data.frame", row.names = c(NA,
-24L))

library(tidyr)
library(dplyr)

df1 <- pedMUM %>%
    group_by(Tattoo.MUM) %>% # find min and max year for each mum
    mutate(
        minyear=min(YearBIRTH.CUB, na.rm=TRUE),
        maxyear=max(YearBIRTH.CUB, na.rm=TRUE)
    ) %>% 
    complete( # complete table
        nesting(Tattoo.MUM, minyear, maxyear, OffspringMUMs, YearBIRTH.MUM),
        YearBIRTH.CUB=full_seq(YearBIRTH.CUB, 1),
        fill=list(OFFSpYR=0)
        ) %>% 
    filter(YearBIRTH.CUB>=minyear & YearBIRTH.CUB<=maxyear) %>% # remove unwanted years
    select(names(pedMUM))  # return original column order