R_Как можно заполнить пробелы в одном столбце средним значением двух других столбцов? - PullRequest
0 голосов
/ 11 октября 2018

Я пытаюсь заполнить пробелы в var1 средним значением var2 и var3, но не могу заставить его работать.Это то, что я до сих пор пробовал:

df <- data.frame(var1=c(1,2,"",3,3,"","",2,2,6,7,3,"","","",3,3,11,12,2,"",3))
df$var2 <- c(1,8,9,1,1,5,8,8,3,2,0,9,4,4,7,3,5,5,2,4,6,6)
df$var3 <- c(4,1,1,4,4,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22)


 for(i in 1:length(df$var1)) {
   ifelse(is.na(df$var1[i]), df$var1[i] <- mean(df$var2[i], df$var3[i]), df$var1[i] == df$var1[i])
 }

Я не уверен, что я делаю неправильно.После запуска кода var1 по-прежнему показывает пустые ячейки.

Большое спасибо за вашу помощь

Ответы [ 3 ]

0 голосов
/ 11 октября 2018

Другой путь без петель:

library(dplyr)

df %>% 
  mutate_at(vars(var1:var3), as.numeric) %>%
  mutate(var1 = case_when(is.na(var1) ~ (var2+var3)/2, TRUE ~ var1))
#>    var1 var2 var3
#> 1   1.0    1    4
#> 2   2.0    8    1
#> 3   5.0    9    1
#> 4   3.0    1    4
#> 5   3.0    1    4
#> 6   5.5    5    6
#> 7   7.5    8    7
#> 8   2.0    8    8
#> 9   2.0    3    9
#> 10  6.0    2   10
#> 11  7.0    0   11
#> 12  3.0    9   12
#> 13  8.5    4   13
#> 14  9.0    4   14
#> 15 11.0    7   15
#> 16  3.0    3   16
#> 17  3.0    5   17
#> 18 11.0    5   18
#> 19 12.0    2   19
#> 20  2.0    4   20
#> 21 13.5    6   21
#> 22  3.0    6   22
0 голосов
/ 12 октября 2018

Я бы использовал подход data.table здесь.Он должен хорошо работать с большими данными и избегать зацикливания ваших данных там, где они вам не нужны.

library(data.table)
dt <- data.table(var1=c(1,2,"",3,3,"","",2,2,6,7,3,"","","",3,3,11,12,2,"",3),
                  var2 = c(1,8,9,1,1,5,8,8,3,2,0,9,4,4,7,3,5,5,2,4,6,6),
                  var3 = c(4,1,1,4,4,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22))
dt[, var1 := as.numeric(var1)]
dt[is.na(var1), var1 := apply(.SD, 1, mean), .SDcols =c("var2", "var3")]

dt


    var1 var2 var3
 1:  1.0    1    4
 2:  2.0    8    1
 3:  5.0    9    1
 4:  3.0    1    4
 5:  3.0    1    4
 6:  5.5    5    6
 7:  7.5    8    7
 8:  2.0    8    8
 9:  2.0    3    9
10:  6.0    2   10
11:  7.0    0   11
12:  3.0    9   12
13:  8.5    4   13
14:  9.0    4   14
15: 11.0    7   15
16:  3.0    3   16
17:  3.0    5   17
18: 11.0    5   18
19: 12.0    2   19
20:  2.0    4   20
21: 13.5    6   21
22:  3.0    6   22
0 голосов
/ 11 октября 2018

Попробуйте это:

df <- data.frame(var1 = c(1,2,"",3,3,"","",2,2,6,7,3,"","","",3,3,11,12,2,"",3),
                 var2 = c(1,8,9,1,1,5,8,8,3,2,0,9,4,4,7,3,5,5,2,4,6,6),
                 var3 = c(4,1,1,4,4,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22),
                 stringsAsFactors = FALSE)
df[df==""] <- "NA"

for (i in 1:length(df$var1)) {
  if (df$var1[i]== "NA") {
    df$var1[i] = rowMeans(df[i, 2:3])
  } else {
    df$var1[i] = df$var1[i]
  }
}

Или:

for (i in 1:length(df[,1])) {
  ifelse (df[i,1] == "NA", df[i,1] <- rowMeans(df[i, 2:3]), df[i,1] <- df[i,1])
}  

В качестве альтернативы, вместо переопределения пробелов как «NA» (как текст в примере выше), вы можете оставить его какпусто, пропуская бит df[df==""] <- "NA":

for (i in 1:length(df[,1])) {
  ifelse (df[i,1] == "", df[i,1] <- rowMeans(df[i, 2:3]), df[i,1] <- df[i,1])
} 

или идентифицировать пробелы как "настоящие" NA:

df[df==""] <- NA

for (i in 1:length(df[,1])) {
  ifelse (is.na(df[i,1]), df[i,1] <- rowMeans(df[i, 2:3]), df[i,1] <- df[i,1])
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...