case_when 可以报告它选择的变量的名称及其值吗?
Can case_when report the names of the variables it selects as well as their values?
我有一个数据集,其中对于每个唯一的 DOI,特定变量的值分散在三个变量(列)的任意组合中。发生这种情况是因为我搜索了三个不同的在线搜索引擎以获取 DOI 信息,并将结果合并到一个文件中。示例数据集如下:
df1 <- data.frame(
'DOI' = c("A","B","C","D","E", "G", "H", "I")
, 'V2' = c(1,NA,NA,4,5,NA,7, NA)
, 'V3' = c(NA,2,NA,4,5,6,NA, NA)
, 'V4' = c(NA,NA,3,4,NA,6,7, NA)
)
df1
DOI V2 V3 V4
1 A 1 NA NA
2 B NA 2 NA
3 C NA NA 3
4 D 4 4 4
5 E 5 5 NA
6 G NA 6 6
7 H 7 NA 7
8 I NA NA NA
下面的代码允许我 select 数据,无论它包含在三列(V2、V3 或 V4)中的哪一列,并将其保存在一个新变量 V5 中。
library(dplyr)
df2 <- df1 %>% mutate(V5 = case_when((!is.na(V2) & is.na(V3) & is.na(V4)) ~ V2,
(is.na(V2) & !is.na(V3) & is.na(V4) ) ~ V3,
(is.na(V2) & is.na(V3) & !is.na(V4) ) ~ V4,
(!is.na(V2) & !is.na(V3) & !is.na(V4) ) ~ V2,
(!is.na(V2) & !is.na(V3) & is.na(V4) ) ~ V3,
(is.na(V2) & !is.na(V3) & !is.na(V4) ) ~ V3,
(!is.na(V2) & is.na(V3) & !is.na(V4) ) ~ V2,
(is.na(V2) & is.na(V3) & is.na(V4) ) ~ V2,
TRUE ~ NA_real_))
df2
DOI V2 V3 V4 V5
1 A 1 NA NA 1
2 B NA 2 NA 2
3 C NA NA 3 3
4 D 4 4 4 4
5 E 5 5 NA 5
6 G NA 6 6 6
7 H 7 NA 7 7
8 I NA NA NA NA
我还想记录(作为 V6),哪些变量(V2、V3 或 V4)是复制到 V5 中的数据的来源。我尝试了以下操作,但它似乎只是复制了进入 V5 的变量的值,而不是变量本身的名称。
df3 <- df2 %>% mutate(V6 = case_when((!is.na(V2) & is.na(V3) & is.na(V4)) ~ "V2",
(is.na(V2) & !is.na(V3) & is.na(V4) ) ~ "V3",
(is.na(V2) & is.na(V3) & !is.na(V4) ) ~ "V4",
(!is.na(V2) & !is.na(V3) & !is.na(V4) ) ~ "V2",
(!is.na(V2) & !is.na(V3) & is.na(V4) ) ~ "V3",
(is.na(V2) & !is.na(V3) & !is.na(V4) ) ~ "V3",
(!is.na(V2) & is.na(V3) & !is.na(V4) ) ~ "V2",
(is.na(V2) & is.na(V3) & is.na(V4) ) ~ "V2",
TRUE ~ NA_real_))
df3
DOI V2 V3 V4 V5 V6
1 A 1 NA NA 1 1
2 B NA 2 NA 2 2
3 C NA NA 3 3 3
4 D 4 4 4 4 4
5 E 5 5 NA 5 5
6 G NA 6 6 6 6
7 H 7 NA 7 7 7
8 I NA NA NA NA NA
是否可以同时记录select编辑数据的变量名称?这将允许跟踪我使用了哪些搜索引擎来查找匹配的 DOI 信息。
这是一个基本的 R 选项,使用 max.col
到 select 每行中的第一个 non-NA 值和相应的列名称。
inds <- max.col(!is.na(df1[-1]), 'first')
df1$V5 <- df1[-1][cbind(1:nrow(df1), inds)]
df1$V6 <- names(df1[-1])[inds]
#To replace column name with all NA value to NA
df1$V6[rowSums(!is.na(df1[-1])) == 0] <- NA
如果您对 dplyr
解决方案感兴趣,您可以将 rowwise
与 c_across
一起使用:
library(dplyr)
df1 %>%
rowwise() %>%
mutate(V5 = na.omit(c_across(V2:V4))[1],
V6 = names(.)[-1][which(!is.na(c_across(V2:V4)))[1]])
# DOI V2 V3 V4 V5 V6
# <chr> <dbl> <dbl> <dbl> <dbl> <chr>
#1 A 1 NA NA 1 V2
#2 B NA 2 NA 2 V3
#3 C NA NA 3 3 V4
#4 D 4 4 4 4 V2
#5 E 5 5 NA 5 V2
#6 G NA 6 6 6 V3
#7 H 7 NA 7 7 V2
#8 I NA NA NA NA NA
我们使用 -1
因为我们想在计算中忽略第一列 DOI
。
使用基数 R:
> df1
DOI V2 V3 V4
1 A 1 NA NA
2 B NA 2 NA
3 C NA NA 3
4 D 4 4 4
5 E 5 5 NA
6 G NA 6 6
7 H 7 NA 7
8 I NA NA NA
> df1$V5 <- apply(df1[2:4], 1, max, na.rm = T)
> df1$V5[is.infinite(df1$V5)] <- NA
> df1$V6 <- apply(df1[2:4],1,which.max)
> df1$V6 <- as.integer(df1$V6)
> df1$V6 <- names(df1)[2:4][df1$V6]
> df1
DOI V2 V3 V4 V5 V6
1 A 1 NA NA 1 V2
2 B NA 2 NA 2 V3
3 C NA NA 3 3 V4
4 D 4 4 4 4 V2
5 E 5 5 NA 5 V2
6 G NA 6 6 6 V3
7 H 7 NA 7 7 V2
8 I NA NA NA NA <NA>
>
我有一个数据集,其中对于每个唯一的 DOI,特定变量的值分散在三个变量(列)的任意组合中。发生这种情况是因为我搜索了三个不同的在线搜索引擎以获取 DOI 信息,并将结果合并到一个文件中。示例数据集如下:
df1 <- data.frame(
'DOI' = c("A","B","C","D","E", "G", "H", "I")
, 'V2' = c(1,NA,NA,4,5,NA,7, NA)
, 'V3' = c(NA,2,NA,4,5,6,NA, NA)
, 'V4' = c(NA,NA,3,4,NA,6,7, NA)
)
df1
DOI V2 V3 V4
1 A 1 NA NA
2 B NA 2 NA
3 C NA NA 3
4 D 4 4 4
5 E 5 5 NA
6 G NA 6 6
7 H 7 NA 7
8 I NA NA NA
下面的代码允许我 select 数据,无论它包含在三列(V2、V3 或 V4)中的哪一列,并将其保存在一个新变量 V5 中。
library(dplyr)
df2 <- df1 %>% mutate(V5 = case_when((!is.na(V2) & is.na(V3) & is.na(V4)) ~ V2,
(is.na(V2) & !is.na(V3) & is.na(V4) ) ~ V3,
(is.na(V2) & is.na(V3) & !is.na(V4) ) ~ V4,
(!is.na(V2) & !is.na(V3) & !is.na(V4) ) ~ V2,
(!is.na(V2) & !is.na(V3) & is.na(V4) ) ~ V3,
(is.na(V2) & !is.na(V3) & !is.na(V4) ) ~ V3,
(!is.na(V2) & is.na(V3) & !is.na(V4) ) ~ V2,
(is.na(V2) & is.na(V3) & is.na(V4) ) ~ V2,
TRUE ~ NA_real_))
df2
DOI V2 V3 V4 V5
1 A 1 NA NA 1
2 B NA 2 NA 2
3 C NA NA 3 3
4 D 4 4 4 4
5 E 5 5 NA 5
6 G NA 6 6 6
7 H 7 NA 7 7
8 I NA NA NA NA
我还想记录(作为 V6),哪些变量(V2、V3 或 V4)是复制到 V5 中的数据的来源。我尝试了以下操作,但它似乎只是复制了进入 V5 的变量的值,而不是变量本身的名称。
df3 <- df2 %>% mutate(V6 = case_when((!is.na(V2) & is.na(V3) & is.na(V4)) ~ "V2",
(is.na(V2) & !is.na(V3) & is.na(V4) ) ~ "V3",
(is.na(V2) & is.na(V3) & !is.na(V4) ) ~ "V4",
(!is.na(V2) & !is.na(V3) & !is.na(V4) ) ~ "V2",
(!is.na(V2) & !is.na(V3) & is.na(V4) ) ~ "V3",
(is.na(V2) & !is.na(V3) & !is.na(V4) ) ~ "V3",
(!is.na(V2) & is.na(V3) & !is.na(V4) ) ~ "V2",
(is.na(V2) & is.na(V3) & is.na(V4) ) ~ "V2",
TRUE ~ NA_real_))
df3
DOI V2 V3 V4 V5 V6
1 A 1 NA NA 1 1
2 B NA 2 NA 2 2
3 C NA NA 3 3 3
4 D 4 4 4 4 4
5 E 5 5 NA 5 5
6 G NA 6 6 6 6
7 H 7 NA 7 7 7
8 I NA NA NA NA NA
是否可以同时记录select编辑数据的变量名称?这将允许跟踪我使用了哪些搜索引擎来查找匹配的 DOI 信息。
这是一个基本的 R 选项,使用 max.col
到 select 每行中的第一个 non-NA 值和相应的列名称。
inds <- max.col(!is.na(df1[-1]), 'first')
df1$V5 <- df1[-1][cbind(1:nrow(df1), inds)]
df1$V6 <- names(df1[-1])[inds]
#To replace column name with all NA value to NA
df1$V6[rowSums(!is.na(df1[-1])) == 0] <- NA
如果您对 dplyr
解决方案感兴趣,您可以将 rowwise
与 c_across
一起使用:
library(dplyr)
df1 %>%
rowwise() %>%
mutate(V5 = na.omit(c_across(V2:V4))[1],
V6 = names(.)[-1][which(!is.na(c_across(V2:V4)))[1]])
# DOI V2 V3 V4 V5 V6
# <chr> <dbl> <dbl> <dbl> <dbl> <chr>
#1 A 1 NA NA 1 V2
#2 B NA 2 NA 2 V3
#3 C NA NA 3 3 V4
#4 D 4 4 4 4 V2
#5 E 5 5 NA 5 V2
#6 G NA 6 6 6 V3
#7 H 7 NA 7 7 V2
#8 I NA NA NA NA NA
我们使用 -1
因为我们想在计算中忽略第一列 DOI
。
使用基数 R:
> df1
DOI V2 V3 V4
1 A 1 NA NA
2 B NA 2 NA
3 C NA NA 3
4 D 4 4 4
5 E 5 5 NA
6 G NA 6 6
7 H 7 NA 7
8 I NA NA NA
> df1$V5 <- apply(df1[2:4], 1, max, na.rm = T)
> df1$V5[is.infinite(df1$V5)] <- NA
> df1$V6 <- apply(df1[2:4],1,which.max)
> df1$V6 <- as.integer(df1$V6)
> df1$V6 <- names(df1)[2:4][df1$V6]
> df1
DOI V2 V3 V4 V5 V6
1 A 1 NA NA 1 V2
2 B NA 2 NA 2 V3
3 C NA NA 3 3 V4
4 D 4 4 4 4 V2
5 E 5 5 NA 5 V2
6 G NA 6 6 6 V3
7 H 7 NA 7 7 V2
8 I NA NA NA NA <NA>
>