在值之间的数据框中填充NA

时间:2018-07-24 17:37:48

标签: r na

我有一个示例数据集

newdata<-data.frame(Tow.y=c(21,"NA","NA","NA","NA","NA",22,"NA","NA","NA","NA","NA",23,"NA","NA"),Tow=c("NA","NA","NA",21,"NA","NA","NA","NA",22,"NA","NA","NA","NA","NA",23))
newdata$Tow.y<-as.numeric(as.character(newdata$Tow.y))
newdata$Tow<-as.numeric(as.character(newdata$Tow))

newdata1<-newdata %>% 
  mutate(Station = coalesce(Tow.y, Tow))
newdata1

结果代码产生:

Tow.y Tow Station
1     21  NA      21
2     NA  NA      NA
3     NA  NA      NA
4     NA  21      21
5     NA  NA      NA
6     NA  NA      NA
7     22  NA      22
8     NA  NA      NA
9     NA  22      22
10    NA  NA      NA
11    NA  NA      NA
12    NA  NA      NA
13    23  NA      23
14    NA  NA      NA
15    NA  23      23

我想为Station中唯一值之间的NA填写NA。因此,两个21值之间的NA将为21,22之间的NA将为22,依此类推。连续数字之间的NA将保持为NA。

赞:

  Tow.y Tow Station
1     21  NA      21
2     NA  NA      21
3     NA  NA      21
4     NA  21      21
5     NA  NA      NA
6     NA  NA      NA
7     22  NA      22
8     NA  NA      22
9     NA  22      22
10    NA  NA      NA
11    NA  NA      NA
12    NA  NA      NA
13    23  NA      23
14    NA  NA      23
15    NA  23      23

我已经在zoo包中尝试了na.locf函数,但是它将替换所有NA值。

newdata1$Station2<-na.locf(newdata1$Station,na.rm = F)

我看过的其他示例显示可以将na.locf与组变量一起使用,但是我没有对数据集完整的分组变量。有人在我需要填写NA的地方填写方法吗?

2 个答案:

答案 0 :(得分:4)

这是个好方法。我将帮助程序列留在其中以演示其工作原理,但是您可以使用select轻松地将其删除。

newdata1 %>%
  mutate(from_first = zoo::na.locf(Station, na.rm = FALSE),
         from_last = zoo::na.locf(Station, na.rm = FALSE, fromLast = TRUE),
         result = if_else(from_first == from_last, from_first, Station))
#    Tow.y Tow Station from_first from_last result
# 1     21  NA      21         21        21     21
# 2     NA  NA      NA         21        21     21
# 3     NA  NA      NA         21        21     21
# 4     NA  21      21         21        21     21
# 5     NA  NA      NA         21        22     NA
# 6     NA  NA      NA         21        22     NA
# 7     22  NA      22         22        22     22
# 8     NA  NA      NA         22        22     22
# 9     NA  22      22         22        22     22
# 10    NA  NA      NA         22        23     NA
# 11    NA  NA      NA         22        23     NA
# 12    NA  NA      NA         22        23     NA
# 13    23  NA      23         23        23     23
# 14    NA  NA      NA         23        23     23
# 15    NA  23      23         23        23     23

答案 1 :(得分:1)

根据示例,似乎“ Tow”和“ Tow.y”值以“开始”,“结束”方式匹配。在这种情况下,我们可以使用base R方法。

创建一个序列索引('i1'),以复制“站”列中“行”(或“ Tow.y”)中的非NA元素。 'lst'返回数字索引的list,该索引用于将值分配给'Station'

lst <- do.call(Map, c(f = seq, unname(lapply(newdata,
          function(x) seq_along(x)[!is.na(x)]))))
i1 <- unlist(lst)    
newdata$Station[i1] <- rep(na.omit(newdata$Tow), lengths(lst))
newdata
#   Tow.y Tow Station
#1     21  NA      21
#2     NA  NA      21
#3     NA  NA      21
#4     NA  21      21
#5     NA  NA      NA
#6     NA  NA      NA
#7     22  NA      22
#8     NA  NA      22
#9     NA  22      22
#10    NA  NA      NA
#11    NA  NA      NA
#12    NA  NA      NA
#13    23  NA      23
#14    NA  NA      23
#15    NA  23      23

或对tidyverse使用相同的逻辑

library(tidyverse)
newdata %>% 
    mutate_all(funs(row_number() * !is.na(.))) %>% 
    map( ~ .x[.x!=0]) %>% 
               transpose %>%
               map(reduce, `:`) %>% 
    set_names(na.omit(newdata$Tow)) %>%
    stack %>%
    right_join(newdata %>% mutate(values = row_number())) %>% 
    rename(Station = ind) %>%
    ungroup %>%

    select(names(newdata), everything(), -values)
#   Tow.y Tow Station
#1     21  NA      21
#2     NA  NA      21
#3     NA  NA      21
#4     NA  21      21
#5     NA  NA    <NA>
#6     NA  NA    <NA>
#7     22  NA      22
#8     NA  NA      22
#9     NA  22      22
#10    NA  NA    <NA>
#11    NA  NA    <NA>
#12    NA  NA    <NA>
#13    23  NA      23
#14    NA  NA      23
#15    NA  23      23