#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
- Но почему мне нужно использовать две простые квадратные скобки, чтобы найти NAs.
- Почему невозможно упростить код, чтобы он был
is.na(df[i, ]) <- impute
? - Существуют ли более эффективные способы замены 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)