用第一个非 NA 填充 data.frame 中的 NA
Filling NA in data.frame with first non NA
我在对数据框中的 NA 值进行插补时遇到了特殊问题,如下例所示。我需要用同一行右侧的第一个非缺失值替换数据框中缺失的数据。例如,我的数据如下所示:
group <-c('A','B','C','D','E','F','G')
year1<- c(NA,'100',NA,'200','300',NA,NA)
year2<- c(NA,'100',NA,'200','300','50','40')
year3<- c('20','100',10,'200','300','150','230')
data=data.frame(group,year1,year2,year3)
但我希望它像最终数据一样:
group <-c('A','B','C','D','E','F','G')
year1<- c('20','100','10','200','300','50','40')
year2<- c('20','100','10','200','300','50','40')
year3<- c('20','100',10,'200','300','150','230')
finaldata=data.frame(group,year1,year2,year3)
我知道有一个函数 na.locf(somevector, fromLast = TRUE)
做类似的事情,但我想在整个数据帧上逐行显示它?
谢谢!
您可以将数据转换为长格式,然后使用 na.locf
:
library(tidyverse)
data %>%
gather(key, value, year1:year3) %>%
group_by(group) %>%
mutate(value = zoo::na.locf(value, na.rm = FALSE, fromLast = TRUE)) %>%
spread(key, value)
输出:
# A tibble: 7 x 4
# Groups: group [7]
group year1 year2 year3
<chr> <chr> <chr> <chr>
1 A 20 20 20
2 B 100 100 100
3 C 10 10 10
4 D 200 200 200
5 E 300 300 300
6 F 50 50 150
7 G 40 40 230
使用(最重要的)coalesce
来自 dplyr
的另一个选项
library(dplyr)
mutate_at(dat,
vars(starts_with("year")),
funs(replace(., is.na(.), do.call(coalesce, dat[-1])[is.na(.)])))
# group year1 year2 year3
#1 A 20 20 20
#2 B 100 100 100
#3 C 10 10 10
#4 D 200 200 200
#5 E 300 300 300
#6 F 50 50 150
#7 G 40 40 230
这里的想法是 replace
NA
对以 "year" 开头的每一列进行 do.call(coalesce, dat[-1])
的结果,即
[1] "20" "100" "10" "200" "300" "50" "40"
这些是每行的第一个非 NA
(由于显而易见的原因排除了第一列)。
数据
dat <- data.frame(group,year1,year2,year3, stringsAsFactors = FALSE)
我在对数据框中的 NA 值进行插补时遇到了特殊问题,如下例所示。我需要用同一行右侧的第一个非缺失值替换数据框中缺失的数据。例如,我的数据如下所示:
group <-c('A','B','C','D','E','F','G')
year1<- c(NA,'100',NA,'200','300',NA,NA)
year2<- c(NA,'100',NA,'200','300','50','40')
year3<- c('20','100',10,'200','300','150','230')
data=data.frame(group,year1,year2,year3)
但我希望它像最终数据一样:
group <-c('A','B','C','D','E','F','G')
year1<- c('20','100','10','200','300','50','40')
year2<- c('20','100','10','200','300','50','40')
year3<- c('20','100',10,'200','300','150','230')
finaldata=data.frame(group,year1,year2,year3)
我知道有一个函数 na.locf(somevector, fromLast = TRUE)
做类似的事情,但我想在整个数据帧上逐行显示它?
谢谢!
您可以将数据转换为长格式,然后使用 na.locf
:
library(tidyverse)
data %>%
gather(key, value, year1:year3) %>%
group_by(group) %>%
mutate(value = zoo::na.locf(value, na.rm = FALSE, fromLast = TRUE)) %>%
spread(key, value)
输出:
# A tibble: 7 x 4
# Groups: group [7]
group year1 year2 year3
<chr> <chr> <chr> <chr>
1 A 20 20 20
2 B 100 100 100
3 C 10 10 10
4 D 200 200 200
5 E 300 300 300
6 F 50 50 150
7 G 40 40 230
使用(最重要的)coalesce
来自 dplyr
library(dplyr)
mutate_at(dat,
vars(starts_with("year")),
funs(replace(., is.na(.), do.call(coalesce, dat[-1])[is.na(.)])))
# group year1 year2 year3
#1 A 20 20 20
#2 B 100 100 100
#3 C 10 10 10
#4 D 200 200 200
#5 E 300 300 300
#6 F 50 50 150
#7 G 40 40 230
这里的想法是 replace
NA
对以 "year" 开头的每一列进行 do.call(coalesce, dat[-1])
的结果,即
[1] "20" "100" "10" "200" "300" "50" "40"
这些是每行的第一个非 NA
(由于显而易见的原因排除了第一列)。
数据
dat <- data.frame(group,year1,year2,year3, stringsAsFactors = FALSE)