R 将NA替换为组中的下一个可用号码
我有一个相对较大的数据集,我想用同一ID号的组内下一年的可用值替换特定年份的价格和特定ID号的NA值。以下是一个可复制的示例:R 将NA替换为组中的下一个可用号码,r,dplyr,group-by,na,imputation,R,Dplyr,Group By,Na,Imputation,我有一个相对较大的数据集,我想用同一ID号的组内下一年的可用值替换特定年份的价格和特定ID号的NA值。以下是一个可复制的示例: ID <- c(1,2,3,2,2,3,1,4,5,5,1,2,2) year <- c(2000,2001,2002,2002,2003,2007,2001,2000,2005,2006,2002,2004,2005) value <- c(1000,20000,30000,NA,40000,NA,6000,4000,NA,20000,7000,50
ID <- c(1,2,3,2,2,3,1,4,5,5,1,2,2)
year <- c(2000,2001,2002,2002,2003,2007,2001,2000,2005,2006,2002,2004,2005)
value <- c(1000,20000,30000,NA,40000,NA,6000,4000,NA,20000,7000,50000,60000)
data <- data.frame(ID, year, value)
ID year value
1 1 2000 1000
2 2 2001 20000
3 3 2002 30000
4 2 2002 NA
5 2 2003 40000
6 3 2007 NA
7 1 2001 6000
8 4 2000 4000
9 5 2005 NA
10 5 2006 20000
11 1 2002 7000
12 2 2004 50000
13 2 2005 60000
因此,在上述情况下,NA应替换为40000(明年的值)。其他身份证也是如此。
最终结果应如下表所示:
ID year value
1 2000 1000
1 2001 6000
1 2002 7000
2 2001 20000
2 2002 40000
2 2003 40000
2 2004 50000
2 2005 60000
3 2007 NA
4 2000 4000
5 2005 20000
5 2006 20000
请注意,对于ID=3,由于没有下一年可用,我们希望保持原样。这就是为什么它是NA的形式
如果您能提出解决方案,我将不胜感激谢谢
dplyr
解决方案
library(tidyverse)
data2 <- data %>%
dplyr::group_by(ID) %>%
dplyr::arrange(year) %>%
dplyr::mutate(replaced_value = ifelse(is.na(value), lead(value), value))
库(tidyverse)
数据2%
dplyr::分组依据(ID)%>%
dplyr::排列(年)%>%
dplyr::mutate(替换的值=ifelse(is.na(值)、lead(值)、value))
打印(数据2)
#一个tibble:13x4
#组别:ID[5]
ID年值替换为年值
1 1 2000 1000 1000
2 4 2000 4000 4000
3 2 2001 20000 20000
4 1 2001 6000 6000
5 3 2002 30000 30000
6.2 2002 NA 40000
7 1 2002 7000 7000
8 2 2003 40000 40000
9 2 2004 50000 50000
10.5 2005 NA 20000
11 2 2005 60000 60000
12 5 2006 20000 20000
13 2007年3月26日不适用
尝试这种tidyverse
方法,使用标志检查连续年份,并fill()
完成数据:
library(tidyverse)
#Data
ID <- c(1,2,3,2,2,3,1,4,5,5,1,2,2)
year <- c(2000,2001,2002,2002,2003,2007,2001,2000,2005,2006,2002,2004,2005)
value <- c(1000,20000,30000,NA,40000,NA,6000,4000,NA,20000,7000,50000,60000)
data <- data.frame(ID, year, value)
#Code
data2 <- data %>% arrange(ID,year) %>%
group_by(ID) %>%
mutate(Flag=c(1,diff(year))) %>%
fill(value,.direction = 'downup') %>%
mutate(value=ifelse(Flag!=1,NA,value)) %>% select(-Flag)
库(tidyverse)
#资料
ID%
mutate(value=ifelse(Flag!=1,NA,value))%>%select(-Flag)
输出:
# A tibble: 13 x 3
# Groups: ID [5]
ID year value
<dbl> <dbl> <dbl>
1 1 2000 1000
2 1 2001 6000
3 1 2002 7000
4 2 2001 20000
5 2 2002 20000
6 2 2003 40000
7 2 2004 50000
8 2 2005 60000
9 3 2002 30000
10 3 2007 NA
11 4 2000 4000
12 5 2005 20000
13 5 2006 20000
# A tibble: 13 x 3
# Groups: ID [5]
ID year value
<dbl> <dbl> <dbl>
1 1 2000 1000
2 1 2001 6000
3 1 2002 7000
4 2 2001 20000
5 2 2002 40000
6 2 2003 40000
7 2 2004 50000
8 2 2005 60000
9 3 2002 30000
10 3 2007 NA
11 4 2000 4000
12 5 2005 20000
13 5 2006 20000
#一个tible:13 x 3
#组别:ID[5]
ID年份值
1 1 2000 1000
2 1 2001 6000
3 1 2002 7000
4 2 2001 20000
5 2 2002 20000
6 2 2003 40000
7 2 2004 50000
8 2 2005 60000
9 3 2002 30000
10 2007年3月26日
11 4 2000 4000
12 5 2005 20000
13 5 2006 20000
您可以执行以下操作:
library(dplyr)
data %>%
group_by(ID) %>%
mutate(value = coalesce(value, as.integer(sapply(pmin(year + 1, max(year)), function(x) value[year == x])))) %>%
arrange(ID, year)
library(tidyverse)
data %>%
arrange(ID, year) %>%
group_by(ID, idx = cumsum(is.na(value))) %>%
fill(value, .direction = 'up') %>%
ungroup %>%
select(-idx)
输出:
# A tibble: 13 x 3
# Groups: ID [5]
ID year value
<dbl> <dbl> <dbl>
1 1 2000 1000
2 1 2001 6000
3 1 2002 7000
4 2 2001 20000
5 2 2002 20000
6 2 2003 40000
7 2 2004 50000
8 2 2005 60000
9 3 2002 30000
10 3 2007 NA
11 4 2000 4000
12 5 2005 20000
13 5 2006 20000
# A tibble: 13 x 3
# Groups: ID [5]
ID year value
<dbl> <dbl> <dbl>
1 1 2000 1000
2 1 2001 6000
3 1 2002 7000
4 2 2001 20000
5 2 2002 40000
6 2 2003 40000
7 2 2004 50000
8 2 2005 60000
9 3 2002 30000
10 3 2007 NA
11 4 2000 4000
12 5 2005 20000
13 5 2006 20000
这在数据中要简单得多(而且可能快得多)。表
:
library(data.table)
setDT(data)[order(ID, year), ][
, value := nafill(value, type = 'nocb'), by = .(ID, cumsum(is.na(value)))]
非常感谢,这种方法似乎对我的数据不起作用。我认为原因是我们应该在分组后对数据进行排序,以确保选择明年的值。你对更新你的代码有什么建议吗?你认为我们应该在“groupby”之后添加“arrange”函数吗?我想你的代码在我上面提供的示例中工作的原因是,每个组的年份都是有序的,这就是为什么这个事实没有影响结果的原因;但是,例如,如果我们将“22003”移到列表的末尾,那么我们就不会得到“22002”的正确答案总之,我相信我们必须根据分组后的“年”对数据进行排序。对吗?