用R中的特定条件替换NA

时间:2018-07-17 09:55:15

标签: r replace na

如果2017年为NA,而2015年和2016年的列具有价值,我想基于同一行将其平均值分配给2017年。

Index   2015            2016            2017
1       NA              6355698         10107023
2       13000000        73050000        NA
4       NA              NA              NA
5       10500000        NA              8000000
6       331000000       659000000       1040000000
7       55500000        NA              32032920
8       NA              NA              20000000
9       2521880         5061370         7044288
...

这是我尝试过的,没用!

ind <- which(is.na(df), arr.ind=TRUE)
df[ind] <- rowMeans(df,  na.rm = TRUE)[ind[,1]]

如果我们在2015年和2017年的列中都有值,而2016年是NA,我想基于同一行将它们的平均值分配给2016年的列。任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

免责声明:我不清楚您的预期输出是什么。我下面的解决方案基于这样一个假设:您想用每年所有值的平均值或每个NA的所有值的平均值替换Index值。 < / p>

这里是一个tidyverse选项,首先从宽范围扩展到长范围,用每年的平均值替换NA,最后从长范围转换为宽范围。

library(tidyverse)
df %>%
    gather(year, value, -Index) %>%
    group_by(year) %>%
    mutate(value = ifelse(is.na(value), mean(value, na.rm = T), value)) %>%
    spread(year, value)
## A tibble: 8 x 4
#  Index     `2015`     `2016`      `2017`
#  <int>      <dbl>      <dbl>       <dbl>
#1     1 115507293.   6355698.   10107023.
#2     2  13000000. 223472356.  186197372.
#3     4 115507293. 223472356.  186197372.
#4     5 115507293. 223472356.    8000000.
#5     6 331000000. 659000000. 1040000000.
#6     7 115507293. 223472356.   32032920.
#7     8 115507293. 223472356.   20000000.
#8     9   2521880.   5061370.    7044288.

请注意,此处我们将NA替换为平均值每年。相反,如果您想用平均值{strong>每个NA 替换Index,只需将group_by(year)替换为group_by(Index)

df %>%
    gather(year, value, -Index) %>%
    group_by(Index) %>%
    mutate(value = ifelse(is.na(value), mean(value, na.rm = T), value)) %>%
    spread(year, value)
## A tibble: 8 x 4
## Groups:   Index [8]
#  Index     `2015`     `2016`      `2017`
#  <int>      <dbl>      <dbl>       <dbl>
#1     1   8231360.   6355698.   10107023.
#2     2  13000000.  13000000.   13000000.
#3     4       NaN        NaN         NaN
#4     5   8000000.   8000000.    8000000.
#5     6 331000000. 659000000. 1040000000.
#6     7  32032920.  32032920.   32032920.
#7     8  20000000.  20000000.   20000000.
#8     9   2521880.   5061370.    7044288.

更新

要仅将NA列中的2017替换为基于20152016值的行平均值

df <- read_table("Index   2015            2016            2017
1       NA              6355698         10107023
2       13000000        73050000        NA
4       NA              NA              NA
5       10500000        NA              8000000
6       331000000       659000000       1040000000
7       55500000        NA              32032920
8       NA              NA              20000000
9       2521880         5061370         7044288")


df %>%
    mutate(`2017` = ifelse(is.na(`2017`), 0.5 * (`2015` + `2016`), `2017`))
## A tibble: 8 x 4
#  Index    `2015`    `2016`      `2017`
#  <int>     <int>     <int>       <dbl>
#1     1        NA   6355698   10107023.
#2     2  13000000  73050000   43025000.
#3     4        NA        NA         NA
#4     5  10500000        NA    8000000.
#5     6 331000000 659000000 1040000000.
#6     7  55500000        NA   32032920.
#7     8        NA        NA   20000000.
#8     9   2521880   5061370    7044288.

样本数据

df <- read_table("Index   2015            2016            2017
1       NA              6355698         10107023
2       13000000        NA              NA
4       NA              NA              NA
5       NA              NA              8000000
6       331000000       659000000       1040000000
7       NA              NA              32032920
8       NA              NA              20000000
9       2521880         5061370         7044288")