R:如果不适用,则根据条件并使用列名称模式,将缺失值替换为另一列中的缺失值

问题描述 投票:0回答:1

我遇到以下问题:对于其中一个

Rating
,6 列中的 3 列数值缺失。

我希望将缺失值替换为位于缺失值列左侧的单元格中的值。 列名有一个清晰的模式 - 它们都以

PD1
PD2
PD3
结尾,可以用作 id

示例:

eePD1
1C、Basic
Rating
和 CORP
Scenario
缺少
Class
列中的值。 仅当
wePD1
为 CORP 时,才应将其替换为
Class
列中的值。(不应触及零售
Class
)。

即,如果 eePD1 中的值为 NAClass=CORP,则 eePD1=wePD1 中的值。

场景 评分 班级 我们PD1 我们PD2 我们PD3 eePD1 eePD2 eePD3
基本 1C 公司 0.51 0.74 0.43 不适用 不适用 不适用
基本 2A 公司 0.41 0.01 0.23 0.37 0.06 0.81
基本 2B 零售 0.68 0.48 0.71 不适用 不适用 不适用

理想的结果:如果从

ee
开始的列中的单元格的值为
NA
(对于 CORP
Rating
以及任何
Class
Scenario
),请将
NA
替换为从
we
开始并结束的列,类似于从
ee
开始的列的名称,例如
PD1
PD2
PD3

场景 评分 班级 我们PD1 我们PD2 我们PD3 eePD1 eePD2 eePD3
基本 1C 公司 0.51 0.74 0.43 0.51 0.74 0.43
基本 2A 公司 0.41 0.01 0.23 0.37 0.06 0.81
基本 2B 零售 0.68 0.48 0.71 不适用 不适用 不适用

这是可重现的代码块:

df3=structure(list(Scenario = c("Basic", "Basic", "Basic", "Basic", "Basic"
    ), Rating = c("1C", "2A", "2B", "2C", "3A"), Class = c("CORP", 
    "CORP", "CORP", "CORP", "RETAIL"), wePD1 = c(0.51, 
    0.41, 0.58, 0.28, 
    0.68), wePD2 = c(0.74, 0.01, 
    0.28, 0.92, 0.48
    ), wePD3 = c(0.43, 0.23, 0.04, 
    0.62, 0.71), eePD1 = c(NA, 0.37, 
    0.96, 0.22, NA
    ), eePD2 = c(NA, 0.06, 0.29, 0.22, 
    NA), eePD3 = c(NA, 0.81, 0.85, 
    0.78, NA)), row.names = c(NA, 
    -5L), class = c("data.table", "data.frame"))

第二个解决方案选项是向左计算三列,但如果我有更多列,它并不优雅或通用......

到目前为止,我只能找到一些

dplyr
示例,这些示例会将值替换为下面/上面的值,但不能替换到两侧,或者基于清晰的列名称模式以获得更好的通用性,例如
purrr
map2_int

r dplyr replace grep purrr
1个回答
0
投票

假设您只有这些列,这样的内容就足够了:

df3$eePD1 <- ifelse(is.na(df3$eePD1) & df3$Class == "CORP", df3$wePD1, df3$eePD1)
df3$eePD2 <- ifelse(is.na(df3$eePD2) & df3$Class == "CORP", df3$wePD2, df3$eePD2)
df3$eePD3 <- ifelse(is.na(df3$eePD3) & df3$Class == "CORP", df3$wePD3, df3$eePD3)

之前:

  Scenario Rating  Class wePD1 wePD2 wePD3 eePD1 eePD2 eePD3
1    Basic     1C   CORP  0.51  0.74  0.43    NA    NA    NA
2    Basic     2A   CORP  0.41  0.01  0.23  0.37  0.06  0.81
3    Basic     2B   CORP  0.58  0.28  0.04  0.96  0.29  0.85
4    Basic     2C   CORP  0.28  0.92  0.62  0.22  0.22  0.78
5    Basic     3A RETAIL  0.68  0.48  0.71    NA    NA    NA

之后:

  Scenario Rating  Class wePD1 wePD2 wePD3 eePD1 eePD2 eePD3
1    Basic     1C   CORP  0.51  0.74  0.43  0.51  0.74  0.43
2    Basic     2A   CORP  0.41  0.01  0.23  0.37  0.06  0.81
3    Basic     2B   CORP  0.58  0.28  0.04  0.96  0.29  0.85
4    Basic     2C   CORP  0.28  0.92  0.62  0.22  0.22  0.78
5    Basic     3A RETAIL  0.68  0.48  0.71    NA    NA    NA

如果您有更多遵循此模式的列,那么您可能希望对其进行概括。但对于三列,我只会采用这种方法。

更通用的解决方案:

for (target in grep("ee", colnames(df3), value=TRUE)) {
  source <- sub("^ee", "we", target)
  df3[[target]] <- ifelse(
    is.na(df3[[target]]) & df3$Class == "CORP",
    df3[[source]],
    df3[[target]]
  )
}
© www.soinside.com 2019 - 2024. All rights reserved.