我有一个像这样的数据框:
ID year mstat change lint
8049 1995 1 NA NA
8049 1996 1 0 1994
8049 1997 1 NA NA
8049 1998 1 0 1996
8049 1999 1 NA NA
8049 2000 1 0 1998
8049 2001 1 NA NA
8049 2002 1 0 2000
8049 2003 NA NA NA
8049 2004 NA NA NA
8049 2005 NA NA NA
8049 2006 NA NA NA
8049 2007 NA NA NA
8049 2008 1 0 2002
8049 2009 NA NA NA
8049 2010 1 0 2008
8049 2011 NA NA NA
8049 2012 2 1 2008
8049 2013 NA NA NA
mstat =婚姻状况,
lint =最后访问日期
change =婚姻状况的变化
对于特定个人,year=2008
中的最后一次采访日期为2002
。 year=2008
中的婚姻状况变化为0
。这意味着2003年至2007年的婚姻状况应与2002年或2008年的婚姻状况相同。我如何使用此人以及整个2002/2008年mstat
填写2003年至2007年的mstat
R中的数据集? (对于不同的个人,缺失值在不同的年份。)
我想要的输出是(从2003年到2007年,在mstat_updated
列中为1。]
ID year mstat change lint mstat_updated
8049 2000 1 0 1998 1
8049 2001 1 NA NA 1
8049 2002 1 0 2000 1
8049 2003 NA NA 2002 1
8049 2004 NA NA 2002 1
8049 2005 NA NA 2002 1
8049 2006 NA NA 2002 1
8049 2007 NA NA 2002 1
8049 2008 1 0 2002 1
8049 2009 NA NA 2008 1
8049 2010 1 0 2008 1
8049 2011 NA NA 2010 NA
8049 2012 2 1 2010 2
[按照Ben的建议尝试了代码之后,我得到了下表,其中所有change
值都是TRUE
。
df %>%
fill(lint, .direction = 'up') %>%
group_by(lint) %>%
mutate(anychange = any(change > 0),
mstat_updated = ifelse(anychange, mstat, last(mstat)))
ID year mstat change lint anychange mstat_updated
8049 1992 1 1 1991 TRUE 1
8049 1993 1 0 1992 TRUE 1
8049 1994 1 0 1993 TRUE 1
8049 1995 NA NA 1994 TRUE NA
8049 1996 1 0 1994 TRUE 1
8049 1997 NA NA 1996 TRUE NA
8049 1998 1 0 1996 TRUE 1
8049 1999 NA NA 1998 TRUE NA
8049 2000 1 0 1998 TRUE 1
8049 2001 NA NA 2000 TRUE NA
8049 2002 1 0 2000 TRUE 1
8049 2003 NA NA 2002 TRUE NA
8049 2004 NA NA 2002 TRUE NA
8049 2005 NA NA 2002 TRUE NA
8049 2006 NA NA 2002 TRUE NA
8049 2007 NA NA 2002 TRUE NA
8049 2008 1 0 2002 TRUE 1
8049 2009 NA NA 2008 TRUE NA
8049 2010 1 0 2008 TRUE 1
8049 2011 NA NA 2008 TRUE NA
8049 2012 2 1 2008 TRUE 2
8049 2013 NA NA 2012 TRUE NA
8049 2014 3 1 2012 TRUE 3
8049 2015 NA NA 2014 TRUE NA
8049 2016 3 0 2014 TRUE 3
head(df,20L)
ID year mstat change lint anychange mstat_updated
<fct> <fct> <int> <int> <dbl> <lgl> <int>
1 8049 1993 1 0 1992 TRUE 1
2 8049 1994 1 0 1993 TRUE 1
3 8049 1995 NA NA 1994 TRUE NA
4 8049 1996 1 0 1994 TRUE 1
5 8049 1997 NA NA 1996 TRUE NA
6 8049 1998 1 0 1996 TRUE 1
7 8049 1999 NA NA 1998 TRUE NA
8 8049 2000 1 0 1998 TRUE 1
9 8049 2001 NA NA 2000 TRUE NA
10 8049 2002 1 0 2000 TRUE 1
11 8049 2003 NA NA 2002 TRUE NA
12 8049 2004 NA NA 2002 TRUE NA
13 8049 2005 NA NA 2002 TRUE NA
14 8049 2006 NA NA 2002 TRUE NA
15 8049 2007 NA NA 2002 TRUE NA
16 8049 2008 1 0 2002 TRUE 1
17 8049 2009 NA NA 2008 TRUE NA
18 8049 2010 1 0 2008 TRUE 1
19 8049 2011 NA NA 2008 TRUE NA
20 8049 2012 2 1 2008 TRUE 2
dput() gives the following structure
structure(list(ID = structure(c(4143L, 4143L, 4143L, 4143L, 4143L,
4143L, 4143L, 4143L, 4143L, 4143L), .Label = c("1", "2", "3",
.............
structure(15:24, .Label = c("1979",
"1980", "1981", "1982", "1983", "1984", "1985", "1986", "1987",
"1988", "1989", "1990", "1991", "1992", "1993", "1994", "1995",
"1996", "1997", "1998", "1999", "2000", "2001", "2002", "2003",
"2004", "2005", "2006", "2007", "2008", "2009", "2010", "2011",
"2012", "2013", "2014", "2015", "2016"), class = "factor"), mstat = c(1L,
1L, NA, 1L, NA, 1L, NA, 1L, NA, 1L), change = c(0L, 0L, NA, 0L,
NA, 0L, NA, 0L, NA, 0L), lint = c(1992, 1993, 1994, 1994, 1996,
1996, 1998, 1998, 2000, 2000), anychange = c(TRUE, TRUE, TRUE,
TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE), mstat_updated = c(1L,
1L, NA, 1L, NA, 1L, NA, 1L, NA, 1L)), class = c("tbl_df", "tbl",
"data.frame"), row.names = c(NA, -10L))
所以,在遵循了Ben绝对有帮助的建议之后,我终于得到了想要的东西。
[首先,我手动修复了棉绒(可能效率不高,但无论如何它都能正常工作),其中棉绒在数据中不正确(例如,Ben指出2012年的数据-上一次面棉是2008年,但有来自2010年)。我的示例代码是:df $ lint_up
然后我填写lint_updated(lint_up
)变量:
mk<-df%>%
group_by(ID)%>%
fill(lint_up,.direction = 'up')
现在,对于mstat_updated
,我主要遵循了Ben的建议,但是我将ID
和lint_up
都分组了。
abc<-mk %>%
group_by(lint_up, ID) %>%
mutate(mstat_updated = ifelse(is.na(mstat) & any(last(change==0)),
last(mstat), mstat))
Edited 10/19/19:
感谢您添加其他信息。我希望这更近。一种tidyverse
方法是使用最后一次采访NA
年的lint
值填写。使用.direction = 'up'
,您将根据最近一年的数据填写。
然后,将group_by
设置为上一个面试年度(lint
),仅根据这些年份进行更改。这将使您可以基于2008 mstat
更改2003-2007年。
我发现的另一个问题是2012年的数据-上一次访问lint
是2008年,但似乎有2010年的数据是最近的。
使用最新的编辑,现在将执行以下操作:
last_year_data
-与lint
相似,但是会在有数据的情况下捕获2010,但缺少lint
change
变量中的NA更改为0-这将捕获any(change)
以标识不应该更新mstat_updated
的位置library(dplyr)
df %>%
filter(!is.na(mstat) & (mstat >= 0)) %>%
mutate(last_year_data = lag(year)) %>%
right_join(df) %>%
fill(last_year_data, .direction = 'up') %>%
group_by(last_year_data) %>%
mutate(mstat_updated = last(mstat),
change = replace_na(change, 0)) %>%
mutate(mstat_updated = ifelse(any(change > 0) & is.na(mstat), mstat, mstat_updated))
# A tibble: 34 x 7
# Groups: last_year_data [20]
ID year mstat change lint last_year_data mstat_updated
<int> <int> <int> <dbl> <int> <int> <int>
1 8049 1983 0 0 1982 1983 0
2 8049 1984 0 0 1983 1983 0
3 8049 1985 0 0 1984 1984 0
4 8049 1986 0 0 1985 1985 0
5 8049 1987 0 0 1986 1986 0
6 8049 1988 0 0 1987 1987 0
7 8049 1989 0 0 1988 1988 0
8 8049 1990 0 0 1989 1989 0
9 8049 1991 0 0 1990 1990 0
10 8049 1992 1 1 1991 1991 1
11 8049 1993 1 0 1992 1992 1
12 8049 1994 1 0 1993 1993 1
13 8049 1995 NA 0 1994 1994 1
14 8049 1996 1 0 1994 1994 1
15 8049 1997 NA 0 1996 1996 1
16 8049 1998 1 0 1996 1996 1
17 8049 1999 NA 0 1998 1998 1
18 8049 2000 1 0 1998 1998 1
19 8049 2001 NA 0 2000 2000 1
20 8049 2002 1 0 2000 2000 1
21 8049 2003 NA 0 2002 2002 1
22 8049 2004 -5 0 2002 2002 1
23 8049 2005 NA 0 2002 2002 1
24 8049 2006 -5 0 2002 2002 1
25 8049 2007 NA 0 2002 2002 1
26 8049 2008 1 0 2002 2002 1
27 8049 2009 NA 0 2008 2008 1
28 8049 2010 1 0 2008 2008 1
29 8049 2011 NA 0 2008 2010 NA
30 8049 2012 2 1 2008 2010 2
31 8049 2013 NA 0 2012 2012 NA
32 8049 2014 3 1 2012 2012 3
33 8049 2015 NA 0 2014 2014 3
34 8049 2016 3 0 2014 2014 3