更新:显然这个特性现在计划在dplyr上使用,正如这里讨论的:https://github.com/tidyverse/dplyr/pull/6145
在SQL中,当验证了给定的情况时,可以分配多个变量,比如var1和var2,构造如下
条件then var1 = x,var2 = y时的情况
dplyr::case_when(或tidyverse中的其他任何东西)是否支持这个有用的功能),如果是这样,如何?!
请注意,在下面的示例中,var1、var2和var3具有完全相同的测试条件,即物种=="setosa",退化情况为TRUE。我想通过不重复这些条件来减少这种冗余:对case_when(或类似)的一次调用,尽管分别对var1、var2和var3使用不同的eval_on_true表达式。显然,在这个例子中,冗余不是问题,但是我的case_when在现实生活中的例子中变得非常大和复杂。
library(tidyverse)
# create example data
set.seed(1337)
data <- iris %>%
sample_n(5) %>%
select(Petal.Length, Petal.Width, Species) %>%
as_tibble()
data
#> # A tibble: 5 × 3
#> Petal.Length Petal.Width Species
#> <dbl> <dbl> <fct>
#> 1 5.5 1.8 virginica
#> 2 5 1.9 virginica
#> 3 1.5 0.2 setosa
#> 4 5.9 2.3 virginica
#> 5 4.1 1.3 versicolor
data %>%
mutate(var1 = case_when(Species == "setosa" ~ "green", TRUE ~ "blue"),
var2 = case_when(Species == "setosa" ~ Petal.Length * 99, TRUE ~ Petal.Length),
var3 = case_when(Species == "setosa" ~ as.Date("2002-12-01"), TRUE ~ as.Date("2003-12-02")))
#> # A tibble: 5 × 6
#> Petal.Length Petal.Width Species var1 var2 var3
#> <dbl> <dbl> <fct> <chr> <dbl> <date>
#> 1 5.5 1.8 virginica blue 5.5 2003-12-02
#> 2 5 1.9 virginica blue 5 2003-12-02
#> 3 1.5 0.2 setosa green 148. 2002-12-01
#> 4 5.9 2.3 virginica blue 5.9 2003-12-02
#> 5 4.1 1.3 versicolor blue 4.1 2003-12-02
由reprex包(v2.0.1)于2022-02-09创建
也许这有帮助:
library(tidyverse)
# create example data
set.seed(1337)
data <- iris %>%
sample_n(5) %>%
as_tibble()
data
#> # A tibble: 5 x 5
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> <dbl> <dbl> <dbl> <dbl> <fct>
#> 1 6.4 3.1 5.5 1.8 virginica
#> 2 6.3 2.5 5 1.9 virginica
#> 3 5.3 3.7 1.5 0.2 setosa
#> 4 6.8 3.2 5.9 2.3 virginica
#> 5 5.7 2.8 4.1 1.3 versicolor
data %>%
mutate(
sepal_size = case_when(
Sepal.Length > 6 & Sepal.Width > 3 ~ "big",
Sepal.Width > 3 ~ "medium",
TRUE ~ "small"
),
petal_size = case_when(
Petal.Length > 5 ~ "big",
TRUE ~ "small"
),
is_fancy = TRUE
)
#> # A tibble: 5 x 8
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species sepal_size
#> <dbl> <dbl> <dbl> <dbl> <fct> <chr>
#> 1 6.4 3.1 5.5 1.8 virginica big
#> 2 6.3 2.5 5 1.9 virginica small
#> 3 5.3 3.7 1.5 0.2 setosa medium
#> 4 6.8 3.2 5.9 2.3 virginica big
#> 5 5.7 2.8 4.1 1.3 versicolor small
#> # … with 2 more variables: petal_size <chr>, is_fancy <lgl>
< sup >创建于2022-02-08,由reprex软件包(2.0.1版)要执行相反的操作,您可以:
iris %>%
mutate(
selected = Species == "setosa",
var1 = ifelse(selected, Petal.Length * 99, Petal.Length),
var2 = ifelse(selected, as.Date("2002-12-01"), as.Date("2003-12-02"))
)
如果我们想通过将具有不同值的单个列相乘来创建新列,一种tidyverse
方法是使用imap
(默认情况下,默认. y
是序列,如果我们传递未命名元素)循环遍历乘数值,返回带有transmute
的单个列,然后将这些列与原始数据绑定
library(purrr)
library(dplyr)
library(stringr)
imap_dfc(c(10, 99), ~ data %>%
transmute(!! str_c('var', .y) :=
case_when(Species == "setosa"~ Petal.Length * .x,
TRUE ~ Petal.Length))) %>%
bind_cols(data, .)
-输出
# A tibble: 5 × 7
Sepal.Length Sepal.Width Petal.Length Petal.Width Species var1 var2
<dbl> <dbl> <dbl> <dbl> <fct> <dbl> <dbl>
1 6.4 3.1 5.5 1.8 virginica 5.5 5.5
2 6.3 2.5 5 1.9 virginica 5 5
3 5.3 3.7 1.5 0.2 setosa 15 148.
4 6.8 3.2 5.9 2.3 virginica 5.9 5.9
5 5.7 2.8 4.1 1.3 versicolor 4.1 4.1
case_when
的问题在于接受长度
为 nrow
或 1 的值。因此,您必须通过生成 nrow
1 行数据帧列表来欺骗case_when
。访问器函数 lod
(定义如下)构造一个 1 行数据帧的列表:
lod <- function(...) {
args <- list(...)
do.call(function(...) mapply(data.frame, ..., SIMPLIFY = FALSE), args)
}
lod(x = 1:4, y = letters[1:4])
[[1]]
x y
1 1 a
[[2]]
x y
1 2 b
[[3]]
x y
1 3 c
[[4]]
x y
1 4 d
然后编写case_when
语句,使用 lod
对变量进行分组,如下所示:
data |>
mutate(case_when(Species == "setosa" ~
lod(var1 = "green",
var2 = Petal.Length * 99,
var3 = as.Date("2002-12-01")),
TRUE ~
lod(var1 = "blue",
var2 = Petal.Length,
var3 = as.Date("2003-12-02"))) |>
bind_rows())
+ # A tibble: 5 x 6
Petal.Length Petal.Width Species var1 var2 var3
<dbl> <dbl> <fct> <chr> <dbl> <date>
1 5.5 1.8 virginica blue 5.5 2003-12-02
2 5 1.9 virginica blue 5 2003-12-02
3 1.5 0.2 setosa green 148. 2002-12-01
4 5.9 2.3 virginica blue 5.9 2003-12-02
5 4.1 1.3 versicolor blue 4.1 2003-12-02
最后的< code>bind_rows是< code>mutate接受新变量所必需的。
问题内容: 我想检查布尔值是否为真,然后在WHERE子句中确定要使用的条件。 假设布尔变量是@checkbool: 有否否定条件的方法?像在C ++中一样,您可以执行!(condition)。 如果不是,解决此问题的最佳方法是什么? 谢谢! 问题答案: SQL在C中的等效项是。但是,在您的情况下,您还需要其他东西:您需要建立一个条件,该条件根据的值在两个选择之间做出决定,如下所示:
问题内容: 在Java中,我想做这样的事情: …代替: 有什么办法吗? 问题答案: 从Java 7开始,这已经成为可能。多捕获块的语法为: 但是请记住,如果所有异常都属于同一类层次结构,则可以简单地捕获该基本异常类型。 还要注意,如果从ExceptionA直接或间接继承了ExceptionB,则不能在同一块中同时捕获ExceptionA和ExceptionB。编译器会抱怨:
这段代码 产生如下数据帧: 我想看到的结果是这个数据框: 因为对于行C有两个条件为真,所以我希望为它们中的每一个创建一行。我怎样才能做到这一点?
当我从Oracle Java教程中读到这篇文章时,我正在查看一个经常重复的谣言,即JVM上的守护进程线程以某种特殊的方式处理块(它们不会,好吗?): 注意:如果在执行或代码时JVM退出,那么块可能不会执行。同样,如果执行或代码的线程被中断或终止,则块可能不会执行,即使应用程序作为一个整体继续。 (重点是我的。)被打断的那一点引起了我的注意! 我认为,如果一个线程处于try/catch代码中并被中断
问题内容: 我想在我的MySQL服务器上执行以下操作: 这在控制台上工作正常,但在我的Java PreparedStatement中却无法正常工作。它在’;’处引发带有语法错误的异常。分离语句。我喜欢该变量,因为我不必重复查找子句,但是如有必要,我可以重写它。与UNION子句相对应的JOIN也有点尴尬。 谢谢, 约书亚记 问题答案: JDBC从未支持解析定界查询。每次调用都是一次数据库访问。也许您
问题内容: 我最近设法将几个手动创建的作业转换为DSL脚本(内联为临时的“种子”作业),并且感到惊讶的是它如此简单。现在,我想摆脱 多个 种子工作,并尝试更整洁地构建事物。 为此,我创建了一个新的存储库,并将所有Groovy DSL脚本提交给它。然后,我创建了一个Jenkins作业,该作业从存储库中提取,并且只有一个 Process Job DSLs 步骤。此步骤已选中 “在文件系统 上 查找”