【发布时间】:2022-08-23 12:18:24
【问题描述】:
我有一个列名列表如下,
cols <- c(\'grade\', \'score\', \'status\')
如果数据框在 cols 向量中没有任何列,我想使用 mutate 和 cross 将该列(值为 NA)添加到数据框中。怎么做?
-
你会接受答案吗不是使用 dplyr mutate 和cross?我认为存在替代解决方案的问题例如this one。
我有一个列名列表如下,
cols <- c(\'grade\', \'score\', \'status\')
如果数据框在 cols 向量中没有任何列,我想使用 mutate 和 cross 将该列(值为 NA)添加到数据框中。怎么做?
base 解决方案:
df[setdiff(cols, names(df))] <- NA
此命令可适用于管道:
df %>%
`[<-`(, setdiff(cols, names(.)), NA)
# id score grade status
# 1 1 94 NA NA
# 2 2 98 NA NA
# 3 3 93 NA NA
# 4 4 82 NA NA
# 5 5 89 NA NA
set.seed(123)
df <- data.frame(id = 1:5, score = sample(80:100, 5))
【讨论】:
dplyr::mutate() 的解决方案假设您的数据框是diamonds。然后在原始数据帧(即diamond这里)中添加一个与列名(即在此MWE中为三列)具有相同列数的tibble数据框。
NA 的小标题要创建一个列数与列名相同的tibble,可以先创建一个matrix,其列数与matrix(ncol = length(cols))的列名相同,然后将其转换为tibble数据框通过as_tibble() 并在as_tibble() 中使用.name_repair = ~ cols 设置列名。
tibble 每一列的值是合乎逻辑的NA,创建矩阵时。请注意,如果您希望稍后将这些新添加的列更改为 integer 列、数字列、复杂列(例如 1 + 5i) 和字符列。在这种情况下,您可以mutate tibble 以便您可以更改列的类型。
您可以在 mutate 中创建这样的 tibble。
cols <- c('grade', 'score', 'status')
diamonds |>
mutate(
matrix(
ncol = length(cols)
) |>
as_tibble(
.name_repair = ~ cols
) |>
## if you want to interpret the grade as `factor` type...
mutate(
grade = as.factor(grade)
)
)
## # A tibble: 53,940 × 13
## carat cut color clarity depth table price x y z grade score
## <dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <fct> <lgl>
## 1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43 NA NA
## 2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31 NA NA
## 3 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31 NA NA
## 4 0.29 Premium I VS2 62.4 58 334 4.2 4.23 2.63 NA NA
## 5 0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75 NA NA
## 6 0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48 NA NA
## 7 0.24 Very Good I VVS1 62.3 57 336 3.95 3.98 2.47 NA NA
## 8 0.26 Very Good H SI1 61.9 55 337 4.07 4.11 2.53 NA NA
## 9 0.22 Fair E VS2 65.1 61 337 3.87 3.78 2.49 NA NA
## 10 0.23 Very Good H VS1 59.4 61 338 4 4.05 2.39 NA NA
## # … with 53,930 more rows, and 1 more variable: status <lgl>
NA tibble为确保仅当原始数据框没有cols 向量中的任何列时才将列添加到原始数据框中,您必须选择NA tibble 数据框中不包含的列存在于原始数据框中。您可以使用!select(matches(colnames(diamonds))) 来做到这一点。
cols <- c("grade", "price", "status")
matrix(ncol = length(cols)) |>
as_tibble(
.name_repair = ~ cols
) |>
mutate(
grade = as.factor(grade)
)
diamonds |>
mutate(
matrix(
ncol = length(cols)
) |>
as_tibble(
.name_repair = ~cols
) |>
## if you want to interpret the grade as `factor` type...
mutate(
grade = as.factor(grade)
) |>
## select columns that are not present in the original data frame
dplyr::select(
!matches(colnames(diamonds))
)
)
## # A tibble: 53,940 × 12
## carat cut color clarity depth table price x y z grade status
## <dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <fct> <lgl>
## 1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43 NA NA
## 2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31 NA NA
## 3 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31 NA NA
## 4 0.29 Premium I VS2 62.4 58 334 4.2 4.23 2.63 NA NA
## 5 0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75 NA NA
## 6 0.24 Very Go… J VVS2 62.8 57 336 3.94 3.96 2.48 NA NA
## 7 0.24 Very Go… I VVS1 62.3 57 336 3.95 3.98 2.47 NA NA
## 8 0.26 Very Go… H SI1 61.9 55 337 4.07 4.11 2.53 NA NA
## 9 0.22 Fair E VS2 65.1 61 337 3.87 3.78 2.49 NA NA
## 10 0.23 Very Go… H VS1 59.4 61 338 4 4.05 2.39 NA NA
## # … with 53,930 more rows
【讨论】:
cols <- c('clarity', 'score', 'status'),您将看到清晰度为@987654350 @。
a = NA、b = NA、...。如果cols 的长度为 100 怎么办?
df <- data.frame(grade = c("A", "B", "C"),
score = c(1, 2, 3))
cols <- c('grade', 'score', 'status')
for (i in cols){
if (!(i %in% colnames(df))){
df[i] <- NA
}
}
> df
grade score status
1 A 1 NA
2 B 2 NA
3 C 3 NA
【讨论】: