我有一个数据框,其中包含许多不同类型的列。我想用相应类的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的所有列进行循环处理呢?
答案 0 :(得分:10)
您可以使用此“技巧”:
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指出,当您选择多个列(例如, :
df[TRUE, 1:3] <- NA
# or
df[1:nrow(df), 1:3] <- NA
答案 1 :(得分:8)
适用于所有列的另一种解决方案可以是指定非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>
答案 2 :(得分:5)
另一种在保留变量类的同时更改所有列的方法:
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)))
答案 3 :(得分:4)
使用 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
答案 4 :(得分:0)
使用bind_cols()
中的dplyr
,您也可以这样做:
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
请注意,这将更改名称。
答案 5 :(得分:0)
另一种使用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>