【问题标题】:r replace missing values with a constant and column name follow a common patternr 用常量替换缺失值,列名遵循通用模式
【发布时间】:2021-12-04 14:42:22
【问题描述】:

我的数据集有这样的列和值。列名都以一个公共字符串 Col_a_** 开头

 ID    Col_a_01    Col_a_02    Col_a_03
 1     1           2           1
 2     1           NA          0
 3     NA          0           2
 4     1           0           1
 5     0           0           2

我的目标是用该列的模式值替换缺失值。

预期的数据集是这样的

  ID    Col_a_01    Col_a_02    Col_a_03
  1     1           2           1
  2     1           0**         0
  3     1**         0           2
  4     1           0           1
  5     0           0           2

第一列的NA被替换为1,因为第一列的众数是1。第二列的NA被替换为0,因为第二列的众数是0。

我可以在下面这样做

getmode <- function(v) {
   uniqv <- unique(v)
   uniqv[which.max(tabulate(match(v, uniqv)))]
}

 df$Col_a_01[is.na(Col_a_01)==TRUE] <- getmode(df$Col_a_01)
 df$Col_a_03[is.na(Col_a_02)==TRUE] <- getmode(df$Col_a_02)
 df$Col_a_03[is.na(Col_a_03)==TRUE] <- getmode(df$Col_a_03)

但是,如果我有 100 列以以 1、2、3..100 结尾的相似名称开头,这将变得笨拙。我很好奇是否有一种更简单、更优雅的方式来实现这一点。提前致谢。

【问题讨论】:

  • @RonakShah,使用模式功能更新问题

标签: r missing-data mode imputation


【解决方案1】:

我们可以使用na.aggregateFUN 指定为getmode

library(zoo)
library(dplyr)
df1 <- df1 %>%
   mutate(across(starts_with('Col_a'), na.aggregate, FUN = getmode))

-输出

df1
  ID Col_a_01 Col_a_02 Col_a_03
1  1        1        2        1
2  2        1        0        0
3  3        1        0        2
4  4        1        0        1
5  5        0        0        2

也可以简单

na.aggregate(df1, FUN = getmode)
ID Col_a_01 Col_a_02 Col_a_03
1  1        1        2        1
2  2        1        0        0
3  3        1        0        2
4  4        1        0        1
5  5        0        0        2

【讨论】:

  • 谢谢。这行得通,但是 starts_with 有点奇怪,如果我使用 starts_with 则它不起作用,如果我将其更改为 matches 则它起作用。挠头。
  • @Science11 matches 采用正则表达式模式。因此,如果有任何不匹配或具有元字符的情况,它可能会以不同的方式解析它。 starts_with 是固定匹配因此,您可能需要检查是否所有列都命名为 Col_
  • 啊,明白了。有些列以相同的字符串开头,但以 _dateTime、_TI 等结尾,例如 Col_a_dateTime、Col_a_TI...
  • @Science11 starts_with 应该匹配这两个,因为提到的前缀是 'Col_a' 否则可能有一些前导/滞后空格或其他字符
【解决方案2】:

您可以使用ifelse/replace 更改NA 的值,以将函数应用于多个列使用dplyr 中的across

library(dplyr)
df <- df %>% 
       mutate(across(starts_with('Col_a'), ~replace(., is.na(.), getmode(.))))

在基础 R 中,使用 lapply -

cols <- grep('Col_a', names(df))
df[cols] <- lapply(df[cols], function(x) replace(x, is.na(x), getmode(x)))

【讨论】:

  • 如果您真的想调试问题,请使用dput 提供数据,因为如果我复制数据并使用它,我会得到df &lt;- structure(list(ID = 1:5, Col_a_01 = c(1L, 1L, NA, 1L, 0L), Col_a_02 = c(2L, NA, 0L, 0L, 0L), Col_a_03 = c(1L, 0L, 2L, 1L, 2L)), class = "data.frame", row.names = c(NA, -5L)) 的数据并且答案有效,我会得到预期的输出。
  • 我认为这可能是我的一连串错误,比其他任何事情都重要。
猜你喜欢
  • 2019-02-18
  • 2023-01-13
  • 2020-08-10
  • 2021-10-11
  • 2021-09-03
  • 2018-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多