【问题标题】:Interpolate NA values with the mean for each row but only for one or two NA values between numerical values用每行的平均值插入 NA 值,但仅针对数值之间的一个或两个 NA 值
【发布时间】:2022-01-09 00:46:16
【问题描述】:

我尝试为每一行插入 NA 值,但我只想在相邻的两个或更少的 NA 值时插入 NA 值。因此,例如在第 3 行中,三个 NA 彼此相邻,所以我不想插值,但在第一行和第二行中,相邻的两个或更少,所以我的目标是线性插值它们。有没有有效的处理方法?

我有一个看起来像这样的数据集:

df1:
   ID string1 2018 2019 2020 2021 2022 string2
1: a1      x2    3    3   NA    4    4      si
2: a2      g3    5    5   NA   NA    1      q2
3: a3      n2   11   NA   NA   NA    3      oq
4: a4      m3    3   NA    9    8    8      mx
5: a5      2w    9    1   NA    5   NA      ix
6: a6     ps2    2   NA    7    4    4      p2
7: a7     kg2    6   NA   NA   NA    6      2q

为了重现性:

df1 = data.table(
  ID = c("a1", "a2", "a3", "a4", "a5", "a6", "a7"),
  "string1" = c("x2", "g3", "n2", "m3", "2w", "ps2", "kg2"),
  "2018" = c(3,5,11,3,9,2,6),
  "2019" = c(3,5,NA,NA,1,NA,NA),
  "2020" = c(NA,NA,NA,9,NA,7,NA),
  "2021" = c(4,NA,NA,8,5,4,NA),
  "2022" = c(4,1,3,8,NA,4,6),
  "string2" = c("si", "q2", "oq", "mx", "ix", "p2", "2q"))

我尝试获取一个看起来像这样的data.table

   ID string1 2018 2019 2020 2021 2022 string2
1: a1      x2    3 3.00  3.5    4    4      si
2: a2      g3    5 5.00  4.3    3    1      q2
3: a3      n2   11   NA   NA   NA    3      oq
4: a4      m3    3 8.25  9.0    8    8      mx
5: a5      2w    9 1.00 -0.3    5   17      ix
6: a6     ps2    2 8.00  7.0    4    4      p2
7: a7     kg2    6   NA  NA    NA    6      2q

感谢您的任何建议!

【问题讨论】:

  • 嗨@fjurt,请在下面找到满足您要求的可能解决方案。请注意,如果我没记错的话,您的问题中所需的结果表中有两个拼写错误:(i)第 5 行,col 2020,应该是 -0.5 而不是 -0.3,(ii)第 5 行,col 2022,应该是 5 而不是 17。干杯。

标签: r data.table


【解决方案1】:

请使用data.tableimputeTS 库找到解决方案(参见下面的reprex)。

Reprex

  • 代码
library(data.table)
library(imputeTS)

results <- df1 %>% 
  transpose(., keep.names = 'rn') %>% 
  {.[3:nrow(df1), lapply(.SD, as.numeric),
  ][, lapply(.SD, na_interpolation, "spline", 2)]} %>% 
  round(., 2) %>%  
  transpose(., make.names = 'rn') %>% 
  cbind(.,df1[,c("ID", "string1", "string2")]) %>% 
  setcolorder(., names(df1))
  • 输出
results
#>        ID string1  2018  2019  2020  2021  2022 string2
#>    <char>  <char> <num> <num> <num> <num> <num>  <char>
#> 1:     a1      x2     3  3.00  3.50     4     4      si
#> 2:     a2      g3     5  5.00  4.33     3     1      q2
#> 3:     a3      n2    11    NA    NA    NA     3      oq
#> 4:     a4      m3     3  8.25  9.00     8     8      mx
#> 5:     a5      2w     9  1.00 -0.50     5     5      ix
#> 6:     a6     ps2     2  8.00  7.00     4     4      p2
#> 7:     a7     kg2     6    NA    NA    NA     6      2q

reprex package (v2.0.1) 于 2021-12-02 创建


使用data.tablezoo 库可能是一个更好的解决方案(参见下面的reprex)。这个解决方案给出了你想要的结果(即忘记我在你的问题下的评论!)

Reprex

  • 代码
library(data.table)
library(zoo)
library(magrittr) # for the pipes! 

results <- df1 %>% 
  transpose(., keep.names = 'rn') %>% 
  {.[3:nrow(df1), lapply(.SD, as.numeric),
  ][, lapply(.SD, na.spline, maxgap = 2)]} %>% 
  round(., 2) %>%  
  transpose(., make.names = 'rn') %>% 
  cbind(.,df1[,c("ID", "string1", "string2")]) %>% 
  setcolorder(., names(df1))
  • 输出
results
#>        ID string1  2018  2019  2020  2021  2022 string2
#>    <char>  <char> <num> <num> <num> <num> <num>  <char>
#> 1:     a1      x2     3  3.00  3.50     4     4      si
#> 2:     a2      g3     5  5.00  4.33     3     1      q2
#> 3:     a3      n2    11    NA    NA    NA     3      oq
#> 4:     a4      m3     3  8.25  9.00     8     8      mx
#> 5:     a5      2w     9  1.00 -0.33     5    17      ix
#> 6:     a6     ps2     2  8.00  7.00     4     4      p2
#> 7:     a7     kg2     6    NA    NA    NA     6      2q

reprex package (v2.0.1) 于 2021-12-03 创建

【讨论】:

  • 嗨@fjurt,我的回答是否满足您的需求?如果是这样,请考虑将此答案标记为“已接受”和/或“赞成”。如果没有,请告诉我有什么问题。干杯。
  • 嘿@lovalery,非常感谢您的回答,很抱歉回复晚了。当我运行您的代码时,它适用于示例数据,但是当我使用另一个数据集运行它时,我得到了错误;未使用的参数(make.names = "rn")。你知道为什么会这样吗?
  • 嗨@fjurt,不用担心延迟:-) 老实说,如果没有看到你的“真实”数据,很难有效地帮助你。以下是一些检查:(i)如果是data.table 库版本问题,请参考我的1.14.2; (ii) 是包含data.table 类的真实数据的表格,而不仅仅是data.frame 类的真实数据; (iii) 你也可以通过只执行前两行来进行测试(即df1 %&gt;% transpose(., keep.names = 'rn')。通常你应该得到一个名为rn的第一列。请告诉我。
  • 嗨@lovalery,非常感谢您的有用评论!我意识到其他安装的软件包导致了问题,当我使用 data.table::transpose() 明确指定函数时,代码工作得非常好:) 非常感谢!
  • 嗨@fjurt。很高兴我能帮助你。我祝你工作顺利。干杯。
猜你喜欢
  • 2016-10-03
  • 1970-01-01
  • 2018-01-04
  • 2011-01-12
  • 2020-08-25
  • 1970-01-01
  • 2016-03-24
  • 2019-03-06
  • 2020-06-08
相关资源
最近更新 更多