我有一个包含多列的数据帧。为了说明我的要求,我缩小了数据帧的大小。
一列"A"具有一组完整的6个值。其余5列"v1"至"v5"随机有2个缺失值,每个缺失值标记为NA。
df <- data.frame('A' = c(2, 4, 7, 5, 3, 4), 'v1' = c(3, NA, NA, 4, 5, 5),
'v2' = c(NA, NA, 6, 4, 5, 5), 'v3' = c(3, 4, NA, NA, 5, 5),
'v4' = c(3, 4, 6, 4, NA, NA), 'v5' = c(3, 4, 6, NA, NA, 5))
A v1 v2 v3 v4 v5
1 2 3.00 1.75 3.00 3.00 3.00
2 4 3.55 3.55 4.00 4.00 4.00
3 7 6.25 6.00 6.25 6.00 6.00
4 5 4.00 4.00 4.45 4.00 4.45
5 3 5.00 5.00 5.00 2.65 2.65
6 4 5.00 5.00 5.00 3.55 5.00
我想做的是使用公式填写数据帧中的所有NA:-0.05+0.9*x。其中x对应于同一行中A列中的值。例如:
对于存在第一个NA的v1行2,Col A=4。所以我希望这个NA填写如下:
-0.05+0.9*4=3.55-------填充3.55
对于v1的第3行NA,其中Col A=7。我想用6.25 填充-0.05+0.9*7=6.25------
我试图使用ifelse((函数,但不知道如何将其应用于整个数据帧,并将其链接到使用同一行中另一列值的等式。
我的尝试如下,我知道这是错误的,但给出了我的方法:
ifelse(df$v1:v5 == NA, -0.05 + 0.9*df$A, df$v1:v5)
基于dplyr
(tidyverse
(的解决方案:
library(dplyr)
my_df <- data.frame('A' = c(2, 4, 7, 5, 3, 4), 'v1' = c(3, NA, NA, 4, 5, 5),
'v2' = c(NA, NA, 6, 4, 5, 5), 'v3' = c(3, 4, NA, NA, 5, 5),
'v4' = c(3, 4, 6, 4, NA, NA), 'v5' = c(3, 4, 6, NA, NA, 5))
my_df %>% mutate_at(vars(-A), ~ifelse(is.na(.), -0.05 + 0.9 * A, .))
结果:
A v1 v2 v3 v4 v5
1 2 3.00 1.75 3.00 3.00 3.00
2 4 3.55 3.55 4.00 4.00 4.00
3 7 6.25 6.00 6.25 6.00 6.00
4 5 4.00 4.00 4.45 4.00 4.45
5 3 5.00 5.00 5.00 2.65 2.65
6 4 5.00 5.00 5.00 3.55 5.00
下面是一个基于循环的、可工作的、但不是很优雅的解决方案。也许你会得到其他的回应。
Indizes = which(is.na(df), arr.ind = TRUE)
for (i in 1:(dim(Indizes)[1])){
df[Indizes[i, 1], Indizes[i, 2]] = -0.05 + 0.9*df[Indizes[i, 1], 1]
}
输出:
A v1 v2 v3 v4 v5
1 2 3.00 1.75 3.00 3.00 3.00
2 4 3.55 3.55 4.00 4.00 4.00
3 7 6.25 6.00 6.25 6.00 6.00
4 5 4.00 4.00 4.45 4.00 4.45
5 3 5.00 5.00 5.00 2.65 2.65
6 4 5.00 5.00 5.00 3.55 5.00