我想创建一个标志,如果13列中的任何一个包含大量代码中的任何一个,则为1,否则为0。我需要使用dplyr,因为我的数据在数据库中。我可以在%语句中使用%%之后完成我的工作。我想知道是否有更简洁的方法来编写此代码。是否存在%in%的版本,允许左侧有多个变量?
以下代码给出了正确的结果。为简洁起见,我只包括5列和2行。
library(dplyr)
match_dx <- c(paste0("C0", 0:9), paste0("C", 10:20))
df <- tibble(dx1 = c("C00", "G01"),
dx2 = c("C50", "Z11"),
dx3 = c("D20", "D22"),
dx4 = c("A40", "C21"),
dx13 = c("G20", "C30"))
df %>%
mutate(flag = case_when(
dx1 %in% match_dx ~ 1,
dx2 %in% match_dx ~ 1,
dx3 %in% match_dx ~ 1,
dx4 %in% match_dx ~ 1,
dx13 %in% match_dx ~ 1,
T ~ 0
))
我想知道是否有像
这样的东西df %>%
mutate(flag = case_when(
any(vars(dx1:dx13) %in% match_dx) ~ 1,
T ~ 0
))
这确实有效,但也许有类似或其他方法可以实现这一点,而不需要每个变量一行。
谢谢!
答案 0 :(得分:4)
这是gather
长期&#39;的一个选项。然后将spread
格式化为&#39; wide&#39;
library(tidyverse)
df %>%
rownames_to_column('rn') %>%
gather(key, val, -rn) %>% group_by(rn) %>%
mutate(flag = as.integer(any(val %in% match_dx))) %>%
spread(key, val)
# A tibble: 2 x 7
# Groups: rn [2]
# rn flag dx1 dx13 dx2 dx3 dx4
#* <chr> <int> <chr> <chr> <chr> <chr> <chr>
#1 1 1 C00 G20 C50 D20 A40
#2 2 0 G01 C30 Z11 D22 C21
或者使用mutate_all
创建逻辑列,然后reduce
将其设置为单个逻辑向量,并mutate
创建&#39;标记&#39;
df %>%
mutate_all(funs(. %in% match_dx)) %>%
reduce(`|`) %>%
as.integer %>%
mutate(df, flag = .)
# A tibble: 2 x 6
# dx1 dx2 dx3 dx4 dx13 flag
# <chr> <chr> <chr> <chr> <chr> <int>
#1 C00 C50 D20 A40 G20 1
#2 G01 Z11 D22 C21 C30 0
或使用@thelatemail
建议的Reduce/lapply
base R
选项
df$flag <- as.integer(Reduce(`|`, lapply(df, is.element, set=match_dx)))
或使用%in%
as.integer(Reduce(`|`, lapply(df, `%in%`, match_dx)))
答案 1 :(得分:3)
我们可以apply
与mutate
一起使用来比较所有列。
library(dplyr)
df %>%
mutate(flag = apply(., 1, function(x) any(x %in% match_dx) * 1))
# # A tibble: 2 x 6
# dx1 dx2 dx3 dx4 dx13 flag
# <chr> <chr> <chr> <chr> <chr> <dbl>
# 1 C00 C50 D20 A40 G20 1
# 2 G01 Z11 D22 C21 C30 0
答案 2 :(得分:3)
注意:我忽略了这些是in-db SQL操作的必要性。这不适用于此。
library(dplyr)
library(purrrlyr)
library(purrr)
df %>%
by_row(~{ as.numeric(any(. %in% match_dx)) }, .to="flag") %>%
mutate(flag = flatten_dbl(flag))
## # A tibble: 2 x 6
## dx1 dx2 dx3 dx4 dx13 flag
## <chr> <chr> <chr> <chr> <chr> <dbl>
## 1 C00 C50 D20 A40 G20 1
## 2 G01 Z11 D22 C21 C30 0
答案 3 :(得分:2)
另一种使用purrr
的替代方案:
library(dplyr)
library(purrr)
df %>% mutate(flag = map_int(transpose(.), ~ any(. %in% match_dx)))
#> # A tibble: 2 x 6
#> dx1 dx2 dx3 dx4 dx13 flag
#> <chr> <chr> <chr> <chr> <chr> <int>
#> 1 C00 C50 D20 A40 G20 1
#> 2 G01 Z11 D22 C21 C30 0