我遇到以下问题:对于其中一个
Rating
,6 列中的 3 列数值缺失。
我希望将缺失值替换为位于缺失值列左侧的单元格中的值。 列名有一个清晰的模式 - 它们都以
PD1
、PD2
或 PD3
结尾,可以用作 id。
示例:
eePD1
1C、Basic Rating
和 CORP Scenario
缺少 Class
列中的值。
仅当 wePD1
为 CORP 时,才应将其替换为 Class
列中的值。(不应触及零售 Class
)。
即,如果 eePD1 中的值为 NA 且 Class=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
。
假设您只有这些列,这样的内容就足够了:
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]]
)
}