这是我关于StackOverflow的第一个问题。我正在尽力在下面创建可复制的示例,但是请告诉我是否有不正确的地方。我已经看到足够多的新手被烧死,所以我希望这可以。
我正在尝试编写一个函数,该函数将使用dplyr :: case_when从包含TRUE-FALSE值的行中返回单个值。如果我对列名进行硬编码,那么一切工作都会很漂亮,但是每当我尝试从其他地方引用该名称时,它就会以字符串形式返回,因此会中断。我已经为此工作了几个小时,所以我一定会错过一些简单的东西。
我尝试使用assign,get和eval(parse))失败。还尝试通过列表,但没有成功。
xcol1 <- c(TRUE, FALSE, FALSE, FALSE, FALSE)
xcol2 <- c(FALSE, TRUE, FALSE, FALSE, FALSE)
xcol3 <- c(FALSE, FALSE, TRUE, FALSE, FALSE)
xcol4 <- c(FALSE, FALSE, FALSE, TRUE, FALSE)
xcol5 <- c(FALSE, FALSE, FALSE, FALSE, TRUE)
ycol1 <- c(TRUE, FALSE, FALSE, FALSE, FALSE)
ycol2 <- c(FALSE, TRUE, FALSE, FALSE, FALSE)
ycol3 <- c(FALSE, FALSE, TRUE, FALSE, FALSE)
ycol4 <- c(FALSE, FALSE, FALSE, TRUE, FALSE)
ycol5 <- c(FALSE, FALSE, FALSE, FALSE, TRUE)
data <- data.frame(xcol1, xcol2, xcol3, xcol4, xcol5, ycol1, ycol2, ycol3, ycol4, ycol5)
colSelect <- "xcol"
names <- setNames(paste0(colSelect, seq(1, 7)), seq(1, 7))
#Works when column names are hard coded
cols <- select(data, contains(colSelect)) %>%
mutate(bad_good = case_when(
xcol1 == TRUE ~ 1,
xcol2 == TRUE ~ 2,
xcol3 == TRUE ~ 3,
xcol4 == TRUE ~ 4,
xcol5 == TRUE ~ 5
)
)
#Doesn't work when column names are referenced from a subset
cols2 <- select(data, contains(colSelect)) %>%
mutate(bad_good = case_when(
names[[1]] == TRUE ~ 1,
names[[2]] == TRUE ~ 2,
names[[3]] == TRUE ~ 3,
names[[4]] == TRUE ~ 4,
names[[5]] == TRUE ~ 5
)
)
从多列TRUE-FALSE值中输出单个列时,我需要能够使用case_when,并且这些列的名称可以从colSelect变量中自定义。
答案 0 :(得分:0)
您需要将names[[x]]
包装在sym()
中,然后使用!!
对其进行评估。您可以通过Google搜索“在Dplyr中编程”
library(tidyverse)
colSelect1 <- "xcol"
names1 <- setNames(paste0(colSelect1, seq(1, 7)), seq(1, 7))
cols1 <- select(data, contains(colSelect1)) %>%
mutate_all(as.logical) %>%
mutate(bad_good = case_when(
!!sym(names1[[1]]) ~ 1,
!!sym(names1[[2]]) ~ 2,
!!sym(names1[[3]]) ~ 3,
!!sym(names1[[4]]) ~ 4,
!!sym(names1[[5]]) ~ 5,
)
)
cols1
#> xcol1 xcol2 xcol3 xcol4 xcol5 bad_good
#> 1 TRUE FALSE FALSE FALSE FALSE 1
#> 2 FALSE TRUE FALSE FALSE FALSE 2
#> 3 FALSE FALSE TRUE FALSE FALSE 3
#> 4 FALSE FALSE FALSE TRUE FALSE 4
#> 5 FALSE FALSE FALSE FALSE TRUE 5
colSelect2 <- "ycol"
names2 <- setNames(paste0(colSelect2, seq(1, 7)), seq(1, 7))
cols2 <- select(data, contains(colSelect2)) %>%
mutate_all(as.logical) %>%
mutate(bad_good = case_when(
!!sym(names2[[1]]) ~ 1,
!!sym(names2[[2]]) ~ 2,
!!sym(names2[[3]]) ~ 3,
!!sym(names2[[4]]) ~ 4,
!!sym(names2[[5]]) ~ 5,
)
)
cols2
#> ycol1 ycol2 ycol3 ycol4 ycol5 bad_good
#> 1 TRUE FALSE FALSE FALSE FALSE 1
#> 2 FALSE TRUE FALSE FALSE FALSE 2
#> 3 FALSE FALSE TRUE FALSE FALSE 3
#> 4 FALSE FALSE FALSE TRUE FALSE 4
#> 5 FALSE FALSE FALSE FALSE TRUE 5
由reprex package(v0.3.0)于2019-07-12创建