用相同类型的 NA 填充列的函数
A function to fill in a column with NA of the same type
我有一个包含许多不同类型列的数据框。我想用相应 class.
的 NA 替换每一列
例如:
df = data_frame(x = c(1,2,3), y = c("a", "b", "c"))
df[, 1:2] <- NA
生成一个包含两个逻辑列的数据框,而不是数字和字符。
我知道我可以告诉 R:
df[,1] = as.numeric(NA)
df[,2] = as.character(NA)
但是我如何在一个循环中针对所有可能类型的 NA 的所有列一起执行此操作?
你可以使用这个 "trick" :
df[1:nrow(df),1] <- NA
df[1:nrow(df),2] <- NA
[1:nrow(df),]
基本上告诉 R 替换 列中的所有值 NA
并且以这种方式强制逻辑 NA
在替换其他值之前更改为列的原始类型。
此外,如果您有很多列要替换并且 data_frame 有很多行,我建议存储行索引并重新使用它们:
rowIdxs <- 1:nrow(df)
df[rowIdxs ,1] <- NA
df[rowIdxs ,2] <- NA
df[rowIdxs ,3] <- NA
...
正如 @RonakShah 巧妙地建议的那样,您还可以使用:
df[TRUE, 1] <- NA
df[TRUE, 2] <- NA
...
正如 @Cath 所指出的,当您 select 多列时,这两种方法仍然有效,例如:
df[TRUE, 1:3] <- NA
# or
df[1:nrow(df), 1:3] <- NA
使用 dplyr
中的 bind_cols()
您还可以:
df <- data_frame(x = c(1,2,3), y = c("a", "b", "c"))
classes <- sapply(df, class)
df[,1:2] <- NA
bind_cols(lapply(colnames(x), function(x){eval(parse(text=paste0("as.", classes[names(classes[x])], "(", df[,x],")")))}))
V1 V2
<dbl> <chr>
1 NA NA
2 NA NA
3 NA NA
请注意,这将更改列名。
适用于所有列的另一种解决方案可以是指定非NA并替换为NA,即
df[!is.na(df)] <- NA
这给出了,
# A tibble: 3 x 2
x y
<dbl> <chr>
1 NA <NA>
2 NA <NA>
3 NA <NA>
使用 dplyr::na_if:
library(dplyr)
df %>%
mutate(x = na_if(x, x),
y = na_if(y, y))
# # A tibble: 3 x 2
# x y
# <dbl> <chr>
# 1 NA NA
# 2 NA NA
# 3 NA NA
如果我们只想将列的子集突变为 NA,则:
# dataframe with extra column that stay unchanged
df = data_frame(x = c(1,2,3), y = c("a", "b", "c"), z = c(4:6))
df %>%
mutate_at(vars(x, y), funs(na_if(.,.)))
# # A tibble: 3 x 3
# x y z
# <dbl> <chr> <int>
# 1 NA NA 4
# 2 NA NA 5
# 3 NA NA 6
同时更改所有列同时保留变量的另一种方法 类:
df[] <- lapply(df, function(x) {type <- class(x); x <- NA; class(x) <- type; x})
df
# A tibble: 3 x 2
# x y
# <dbl> <chr>
#1 NA <NA>
#2 NA <NA>
#3 NA <NA>
正如@digEmAll 在评论中指出的那样,还有另一种类似但更短的方法:
df[] <- lapply(df, function(x) as(NA,class(x)))
另一种方法使用dplyr
:
df <- tibble(x = c(1,2,3), y = c("a", "b", "c"))
df
#> # A tibble: 3 x 2
#> x y
#> <dbl> <chr>
#> 1 1 a
#> 2 2 b
#> 3 3 c
df %>%
mutate(across(everything(), ~as(NA, class(.x))))
#> # A tibble: 3 x 2
#> x y
#> <dbl> <chr>
#> 1 NA <NA>
#> 2 NA <NA>
#> 3 NA <NA>
我有一个包含许多不同类型列的数据框。我想用相应 class.
的 NA 替换每一列例如:
df = data_frame(x = c(1,2,3), y = c("a", "b", "c"))
df[, 1:2] <- NA
生成一个包含两个逻辑列的数据框,而不是数字和字符。 我知道我可以告诉 R:
df[,1] = as.numeric(NA)
df[,2] = as.character(NA)
但是我如何在一个循环中针对所有可能类型的 NA 的所有列一起执行此操作?
你可以使用这个 "trick" :
df[1:nrow(df),1] <- NA
df[1:nrow(df),2] <- NA
[1:nrow(df),]
基本上告诉 R 替换 列中的所有值 NA
并且以这种方式强制逻辑 NA
在替换其他值之前更改为列的原始类型。
此外,如果您有很多列要替换并且 data_frame 有很多行,我建议存储行索引并重新使用它们:
rowIdxs <- 1:nrow(df)
df[rowIdxs ,1] <- NA
df[rowIdxs ,2] <- NA
df[rowIdxs ,3] <- NA
...
正如 @RonakShah 巧妙地建议的那样,您还可以使用:
df[TRUE, 1] <- NA
df[TRUE, 2] <- NA
...
正如 @Cath 所指出的,当您 select 多列时,这两种方法仍然有效,例如:
df[TRUE, 1:3] <- NA
# or
df[1:nrow(df), 1:3] <- NA
使用 dplyr
中的 bind_cols()
您还可以:
df <- data_frame(x = c(1,2,3), y = c("a", "b", "c"))
classes <- sapply(df, class)
df[,1:2] <- NA
bind_cols(lapply(colnames(x), function(x){eval(parse(text=paste0("as.", classes[names(classes[x])], "(", df[,x],")")))}))
V1 V2
<dbl> <chr>
1 NA NA
2 NA NA
3 NA NA
请注意,这将更改列名。
适用于所有列的另一种解决方案可以是指定非NA并替换为NA,即
df[!is.na(df)] <- NA
这给出了,
# A tibble: 3 x 2 x y <dbl> <chr> 1 NA <NA> 2 NA <NA> 3 NA <NA>
使用 dplyr::na_if:
library(dplyr)
df %>%
mutate(x = na_if(x, x),
y = na_if(y, y))
# # A tibble: 3 x 2
# x y
# <dbl> <chr>
# 1 NA NA
# 2 NA NA
# 3 NA NA
如果我们只想将列的子集突变为 NA,则:
# dataframe with extra column that stay unchanged
df = data_frame(x = c(1,2,3), y = c("a", "b", "c"), z = c(4:6))
df %>%
mutate_at(vars(x, y), funs(na_if(.,.)))
# # A tibble: 3 x 3
# x y z
# <dbl> <chr> <int>
# 1 NA NA 4
# 2 NA NA 5
# 3 NA NA 6
同时更改所有列同时保留变量的另一种方法 类:
df[] <- lapply(df, function(x) {type <- class(x); x <- NA; class(x) <- type; x})
df
# A tibble: 3 x 2
# x y
# <dbl> <chr>
#1 NA <NA>
#2 NA <NA>
#3 NA <NA>
正如@digEmAll 在评论中指出的那样,还有另一种类似但更短的方法:
df[] <- lapply(df, function(x) as(NA,class(x)))
另一种方法使用dplyr
:
df <- tibble(x = c(1,2,3), y = c("a", "b", "c"))
df
#> # A tibble: 3 x 2
#> x y
#> <dbl> <chr>
#> 1 1 a
#> 2 2 b
#> 3 3 c
df %>%
mutate(across(everything(), ~as(NA, class(.x))))
#> # A tibble: 3 x 2
#> x y
#> <dbl> <chr>
#> 1 NA <NA>
#> 2 NA <NA>
#> 3 NA <NA>