Почему две одиночные квадратные скобки рядом в R

#r #na #data-cleaning #square-bracket

Вопрос:

Я пытаюсь научиться очистке данных с помощью простого кода.

Мой главный вопрос заключается в следующем: для чего используются две квадратные скобки рядом?

Вот df в качестве примера.

 df <- data.frame(x = c(1:3, NA, NA), y = c(6:9, NA))
 

Следующий код-один из многих способов заменить NAs, скажем, 99. И я думаю, что это довольно просто.

 messy <- function(df, impute){
for (i in 1:nrow(df)) {
df[i, ][is.na(df[i, ])] <- impute
}
return(df)
}
 
 clean <- messy(df, 99)
clean
 
  1. Но почему мне нужно использовать две простые квадратные скобки, чтобы найти NAs.
  2. Почему невозможно упростить код, чтобы он был is.na(df[i, ]) <- impute ?
  3. Существуют ли более эффективные способы замены NAs, такие как использование семейства apply?

Большое спасибо за ответ.

Комментарии:

1. К вашему сведению, в пакете dplyr есть replace_na() пакет, который делает именно это.

Ответ №1:

Это очень сложный способ замены NA «s». Вы можете уменьшить функцию до —

 messy <- function(df, impute){
  df[is.na(df)] <- impute
  df
}

clean <- messy(df, 99)
clean

#   x  y
#1  1  6
#2  2  7
#3  3  8
#4 99  9
#5 99 99
 

Вы также можете использовать apply семейство функций, но они здесь не нужны, так is.na как работают непосредственно с кадрами данных.

Комментарии:

1. Спасибо! Ваше предложение простое и быстрое! Если я настаиваю на использовании apply , что мне делать?

2. Вы можете использовать df[] <- lapply(df, function(x) replace(x, is.na(x), impute)) . Это также можно использовать с apply построчным или столбчатым отображением.

3. Сказав это, могу я узнать, почему в этой строке кода есть две квадратные скобки? df[i, ][is.na(df[i, ])] Спасибо.

4. Первый ( df[i, ] ) подмножество строки, а второй подмножество NA значения из этой строки ( is.na(df[i, ])] ).

Ответ №2:

Вот еще три способа заменить NA на подход tidyverse:

 library(tidyverse)

df <- data.frame(x = c(1:3, NA, NA), y = c(6:9, NA))

#purrr 
map_df(df, ~replace_na(.x, 99))
#> # A tibble: 5 x 2
#>       x     y
#>   <dbl> <dbl>
#> 1     1     6
#> 2     2     7
#> 3     3     8
#> 4    99     9
#> 5    99    99

#transmute/across
df %>% transmute(across(everything(), ~replace_na(.x, 99)))
#>    x  y
#> 1  1  6
#> 2  2  7
#> 3  3  8
#> 4 99  9
#> 5 99 99

#transmute_if
df %>% transmute_if(is.numeric, ~replace_na(.x, 99))
#>    x  y
#> 1  1  6
#> 2  2  7
#> 3  3  8
#> 4 99  9
#> 5 99 99
 

Создано 2021-06-14 пакетом reprex (v2.0.0)