R 将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号的组内下一年的可用值替换特定年份的价格和特定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,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”的正确答案总之,我相信我们必须根据分组后的“年”对数据进行排序。对吗?