R 为除 * 之外的所有列替换 NA
R Replace NA for all Columns Except *
library(tidyverse)
df <- tibble(Date = c(rep(as.Date("2020-01-01"), 3), NA),
col1 = 1:4,
thisCol = c(NA, 8, NA, 3),
thatCol = 25:28,
col999 = rep(99, 4))
#> # A tibble: 4 x 5
#> Date col1 thisCol thatCol col999
#> <date> <int> <dbl> <int> <dbl>
#> 1 2020-01-01 1 NA 25 99
#> 2 2020-01-01 2 8 26 99
#> 3 2020-01-01 3 NA 27 99
#> 4 NA 4 3 28 99
我的实际 R 数据框有数百个列,这些列没有整齐地命名,但可以用上面的 df
数据框近似。
我想用 0
替换 NA
的所有值,但有几列除外(在我的示例中,我想省略 Date
列和 thatCol
专栏。我想以这种方式进行:
df %>% replace(is.na(.), 0)
#> Error: Assigned data `values` must be compatible with existing data.
#> i Error occurred for column `Date`.
#> x Can't convert <double> to <date>.
#> Run `rlang::last_error()` to see where the error occurred.
我完成 "everything except" 替换 NA 的不成功想法如下所示。
df %>% replace(is.na(c(., -c(Date, thatCol)), 0))
df %>% replace_na(list([, c(2:3, 5)] = 0))
df %>% replace_na(list(everything(-c(Date, thatCol)) = 0))
有没有办法 select 一切都按照我需要的方式进行?有数百列,命名不一致,因此一一键入它们是不切实际的选择。
根据data.table
,您有多个选项here。
最酷的选项之一:setnafill
(版本 >= 1.12.4):
library(data.table)
setDT(df)
data.table::setnafill(df,fill = 0, cols = colnames(df)[!(colnames(df) %in% c("Date", thatCol)]))
请注意,您的数据框是通过引用更新的。
您可以使用 mutate_at
:
library(dplyr)
按名称删除它们
df %>% mutate_at(vars(-c(Date, thatCol)), ~replace(., is.na(.), 0))
按位置删除它们
df %>% mutate_at(-c(1,4), ~replace(., is.na(.), 0))
Select 他们的名字
df %>% mutate_at(vars(col1, thisCol, col999), ~replace(., is.na(.), 0))
Select 他们的位置
df %>% mutate_at(c(2, 3, 5), ~replace(., is.na(.), 0))
如果你想使用replace_na
df %>% mutate_at(vars(-c(Date, thatCol)), tidyr::replace_na, 0)
请注意 mutate_at
即将在 dplyr 1.0.0
中被 across
取代。
如果你知道那些你不想改变的,你可以这样做:
df <- tibble(Date = c(rep(as.Date("2020-01-01"), 3), NA),
col1 = 1:4,
thisCol = c(NA, 8, NA, 3),
thatCol = 25:28,
col999 = rep(99, 4))
#dplyr
df_nonreplace <- select(df, c("Date", "thatCol"))
df_replace <- df[ ,!names(df) %in% names(df_nonreplace)]
df_replace[is.na(df_replace)] <- 0
df <- cbind(df_nonreplace, df_replace)
> head(df)
Date thatCol col1 thisCol col999
1 2020-01-01 25 1 0 99
2 2020-01-01 26 2 8 99
3 2020-01-01 27 3 0 99
4 <NA> 28 4 3 99
另一个base
解决方案:
to_change<-grep("^(this|col)",names(df))
df[to_change]<- sapply(df[to_change],function(x) replace(x,is.na(x),0))
df
# A tibble: 4 x 5
Date col1 thisCol thatCol col999
<date> <dbl> <dbl> <int> <dbl>
1 2020-01-01 1 0 25 99
2 2020-01-01 2 8 26 99
3 2020-01-01 3 0 27 99
4 NA 0 3 28 99
数据(我改了一个值):
df <- structure(list(Date = structure(c(18262, 18262, 18262, NA), class = "Date"),
col1 = c(1L, 2L, 3L, NA), thisCol = c(NA, 8, NA, 3), thatCol = 25:28,
col999 = c(99, 99, 99, 99)), row.names = c(NA, -4L), class = c("tbl_df",
"tbl", "data.frame"))
replace
在 data.frame 上工作,所以我们可以通过索引进行替换并更新原始数据集
df[-c(1, 4)] <- replace(df[-c(1, 4)], is.na(df[-c(1, 4)]), 0)
或使用 replace_na
和 across
(来自新的 dplyr
)
library(dplyr)
library(tidyr)
df %>%
mutate(across(-c(Date, thatCol), ~ replace_na(., 0)))
library(tidyverse)
df <- tibble(Date = c(rep(as.Date("2020-01-01"), 3), NA),
col1 = 1:4,
thisCol = c(NA, 8, NA, 3),
thatCol = 25:28,
col999 = rep(99, 4))
#> # A tibble: 4 x 5
#> Date col1 thisCol thatCol col999
#> <date> <int> <dbl> <int> <dbl>
#> 1 2020-01-01 1 NA 25 99
#> 2 2020-01-01 2 8 26 99
#> 3 2020-01-01 3 NA 27 99
#> 4 NA 4 3 28 99
我的实际 R 数据框有数百个列,这些列没有整齐地命名,但可以用上面的 df
数据框近似。
我想用 0
替换 NA
的所有值,但有几列除外(在我的示例中,我想省略 Date
列和 thatCol
专栏。我想以这种方式进行:
df %>% replace(is.na(.), 0)
#> Error: Assigned data `values` must be compatible with existing data.
#> i Error occurred for column `Date`.
#> x Can't convert <double> to <date>.
#> Run `rlang::last_error()` to see where the error occurred.
我完成 "everything except" 替换 NA 的不成功想法如下所示。
df %>% replace(is.na(c(., -c(Date, thatCol)), 0))
df %>% replace_na(list([, c(2:3, 5)] = 0))
df %>% replace_na(list(everything(-c(Date, thatCol)) = 0))
有没有办法 select 一切都按照我需要的方式进行?有数百列,命名不一致,因此一一键入它们是不切实际的选择。
根据data.table
,您有多个选项here。
最酷的选项之一:setnafill
(版本 >= 1.12.4):
library(data.table)
setDT(df)
data.table::setnafill(df,fill = 0, cols = colnames(df)[!(colnames(df) %in% c("Date", thatCol)]))
请注意,您的数据框是通过引用更新的。
您可以使用 mutate_at
:
library(dplyr)
按名称删除它们
df %>% mutate_at(vars(-c(Date, thatCol)), ~replace(., is.na(.), 0))
按位置删除它们
df %>% mutate_at(-c(1,4), ~replace(., is.na(.), 0))
Select 他们的名字
df %>% mutate_at(vars(col1, thisCol, col999), ~replace(., is.na(.), 0))
Select 他们的位置
df %>% mutate_at(c(2, 3, 5), ~replace(., is.na(.), 0))
如果你想使用replace_na
df %>% mutate_at(vars(-c(Date, thatCol)), tidyr::replace_na, 0)
请注意 mutate_at
即将在 dplyr 1.0.0
中被 across
取代。
如果你知道那些你不想改变的,你可以这样做:
df <- tibble(Date = c(rep(as.Date("2020-01-01"), 3), NA),
col1 = 1:4,
thisCol = c(NA, 8, NA, 3),
thatCol = 25:28,
col999 = rep(99, 4))
#dplyr
df_nonreplace <- select(df, c("Date", "thatCol"))
df_replace <- df[ ,!names(df) %in% names(df_nonreplace)]
df_replace[is.na(df_replace)] <- 0
df <- cbind(df_nonreplace, df_replace)
> head(df)
Date thatCol col1 thisCol col999
1 2020-01-01 25 1 0 99
2 2020-01-01 26 2 8 99
3 2020-01-01 27 3 0 99
4 <NA> 28 4 3 99
另一个base
解决方案:
to_change<-grep("^(this|col)",names(df))
df[to_change]<- sapply(df[to_change],function(x) replace(x,is.na(x),0))
df
# A tibble: 4 x 5
Date col1 thisCol thatCol col999
<date> <dbl> <dbl> <int> <dbl>
1 2020-01-01 1 0 25 99
2 2020-01-01 2 8 26 99
3 2020-01-01 3 0 27 99
4 NA 0 3 28 99
数据(我改了一个值):
df <- structure(list(Date = structure(c(18262, 18262, 18262, NA), class = "Date"),
col1 = c(1L, 2L, 3L, NA), thisCol = c(NA, 8, NA, 3), thatCol = 25:28,
col999 = c(99, 99, 99, 99)), row.names = c(NA, -4L), class = c("tbl_df",
"tbl", "data.frame"))
replace
在 data.frame 上工作,所以我们可以通过索引进行替换并更新原始数据集
df[-c(1, 4)] <- replace(df[-c(1, 4)], is.na(df[-c(1, 4)]), 0)
或使用 replace_na
和 across
(来自新的 dplyr
)
library(dplyr)
library(tidyr)
df %>%
mutate(across(-c(Date, thatCol), ~ replace_na(., 0)))