将变量的名称分配给具有多个变量的数据框中的非 NA
Assign the name of the variable to a non NA in a data frame with multiple variables
比如我的df是:
>dfABy
A B C
56 NA NA
NA 45 NA
NA 77 NA
67 NA 12
NA 65 3
我要实现如下数据框
>dfABy
A B C
A NA NA
NA B NA
NA B NA
A NA C
NA B C
这是base R
中的一个选项。将数据转换为逻辑矩阵,非 NA 为 TRUE,NA 为 FALSE。根据 col
um 索引 ('nm1') 复制列名。根据索引'i1'将数据中的元素赋值给对应的列名
i1 <- !is.na(dfABy)
nm1 <- names(dfABy)[col(dfABy)]
dfABy[i1] <- nm1[i1]
-输出
dfABy
# A B C
#1 A <NA> <NA>
#2 <NA> B <NA>
#3 <NA> B <NA>
#4 A <NA> C
#5 <NA> B C
或单行
dfABy[] <- names(dfABy)[col(dfABy)][(NA^is.na(dfABy)) * col(dfABy)]
或使用tidyverse
library(dplyr)
dfABy %>%
mutate(across(everything(), ~ replace(., !is.na(.), cur_column())))
# A B C
#1 A <NA> <NA>
#2 <NA> B <NA>
#3 <NA> B <NA>
#4 A <NA> C
#5 <NA> B C
数据
dfABy <- structure(list(A = c(56L, NA, NA, 67L, NA), B = c(NA, 45L, 77L,
NA, 65L), C = c(NA, NA, NA, 12L, 3L)), class = "data.frame", row.names = c(NA,
-5L))
另一种选择是使用 purrr
包:
library(purrr)
df <- data.frame(A = c(56, NA, NA, 67, NA), B = c(NA, 45, 77, NA, 65), C = c(NA, NA, NA,12, 3))
imap_dfc(df, ~ifelse(is.na(.x), NA, .y))
# A tibble: 5 x 3
A B C
<chr> <chr> <chr>
1 A NA NA
2 NA B NA
3 NA B NA
4 A NA C
5 NA B C
Map
的基本 R 选项:
dfABy[] <- Map(function(x, y) ifelse(is.na(x), NA, y), dfABy, names(dfABy))
dfABy
# A B C
#1 A <NA> <NA>
#2 <NA> B <NA>
#3 <NA> B <NA>
#4 A <NA> C
#5 <NA> B C
比如我的df是:
>dfABy
A B C
56 NA NA
NA 45 NA
NA 77 NA
67 NA 12
NA 65 3
我要实现如下数据框
>dfABy
A B C
A NA NA
NA B NA
NA B NA
A NA C
NA B C
这是base R
中的一个选项。将数据转换为逻辑矩阵,非 NA 为 TRUE,NA 为 FALSE。根据 col
um 索引 ('nm1') 复制列名。根据索引'i1'将数据中的元素赋值给对应的列名
i1 <- !is.na(dfABy)
nm1 <- names(dfABy)[col(dfABy)]
dfABy[i1] <- nm1[i1]
-输出
dfABy
# A B C
#1 A <NA> <NA>
#2 <NA> B <NA>
#3 <NA> B <NA>
#4 A <NA> C
#5 <NA> B C
或单行
dfABy[] <- names(dfABy)[col(dfABy)][(NA^is.na(dfABy)) * col(dfABy)]
或使用tidyverse
library(dplyr)
dfABy %>%
mutate(across(everything(), ~ replace(., !is.na(.), cur_column())))
# A B C
#1 A <NA> <NA>
#2 <NA> B <NA>
#3 <NA> B <NA>
#4 A <NA> C
#5 <NA> B C
数据
dfABy <- structure(list(A = c(56L, NA, NA, 67L, NA), B = c(NA, 45L, 77L,
NA, 65L), C = c(NA, NA, NA, 12L, 3L)), class = "data.frame", row.names = c(NA,
-5L))
另一种选择是使用 purrr
包:
library(purrr)
df <- data.frame(A = c(56, NA, NA, 67, NA), B = c(NA, 45, 77, NA, 65), C = c(NA, NA, NA,12, 3))
imap_dfc(df, ~ifelse(is.na(.x), NA, .y))
# A tibble: 5 x 3
A B C
<chr> <chr> <chr>
1 A NA NA
2 NA B NA
3 NA B NA
4 A NA C
5 NA B C
Map
的基本 R 选项:
dfABy[] <- Map(function(x, y) ifelse(is.na(x), NA, y), dfABy, names(dfABy))
dfABy
# A B C
#1 A <NA> <NA>
#2 <NA> B <NA>
#3 <NA> B <NA>
#4 A <NA> C
#5 <NA> B C