匹配条件时写入其他列
Writing other columns when matching a condition
我想创建一个新列,仅在它符合特定条件时记录它(此处 x > 2
),然后 直接 覆盖另一个现有列(此处auxiliary
) 对于条件 (x > 2
) 返回 TRUE 的这些行。
df <- tibble(x = 1:5, y = 1:5, auxiliary = NA)
# A tibble: 5 x 3
x y auxiliary
<int> <dbl> <lgl>
1 1 NA
2 2 NA
3 3 NA
4 4 NA
5 5 NA
我可以在 mutate()
内的两个不同调用中成功完成此操作:
df %>%
mutate(result = if_else(condition = x > 2,
true = x+y,
false = NA_real_),
auxiliary = if_else(condition = x > 2,
true = "Calculation done",
false = NA_character_))
# A tibble: 5 x 4
x y auxiliary result
<int> <dbl> <chr> <dbl>
1 1 NA NA
2 2 NA NA
3 3 Calculation done 6
4 4 Calculation done 8
5 5 Calculation done 10
但是有一些代码重复(condition = x > 2
),在更复杂的情况下,这使得阅读代码非常困难并且容易出错,尤其是在有多个条件时。
有没有办法通过不重复条件来简化上面的代码? :
- 创建新变量(
mutate()
)
- 仅当条件匹配时才记录(
if_else
或 case_when()
)
- 仅当行的条件匹配时写入另一列的值。 (我被困在这里)
看起来像这样的东西:
df %>%
mutate(result = case_when(
x > 2 ~ x + y & auxiliary == "Calculation done", # we'd add the column reference here...
TRUE ~ NA_real & auxiliary = NA_character_))
非常感谢!来自 tidyverse 的任何解决方案都是理想的。
我建议将应该多次使用的条件保存为字符串,然后在代码中使用该字符串作为变量,例如:
condition <- "x>2"
df %>%
mutate(result = ifelse(eval(parse(text=condition)),
x+y,
NA),
auxiliary = ifelse(eval(parse(text=condition)),
"Calculation done",
NA))
请注意,我使用的是基本 ifelse 语句,以避免我必须在列中使用相同类型的限制(“dplyr::if_else 专门用于强制您使用相同的类型输入你的真假论点。”)。查看更多信息,例如Different behavior of if else statement and if_else.
您可以将条件的结果保存在列中并使用它来避免一次又一次地评估相同的条件。
library(dplyr)
df <- tibble(x = 1:5, y = 1:5)
df %>%
mutate(condition = x > 2,
result = if_else(condition,
true = x+y,
false = NA_integer_),
auxiliary = if_else(condition,
true = "Calculation done",
false = NA_character_))
# x y condition result auxiliary
# <int> <int> <lgl> <int> <chr>
#1 1 1 FALSE NA NA
#2 2 2 FALSE NA NA
#3 3 3 TRUE 6 Calculation done
#4 4 4 TRUE 8 Calculation done
#5 5 5 TRUE 10 Calculation done
可以实现您想要的那种抽象,但确实需要更多的设置。 mutate
其实比你想象的要灵活。您可以将脚本传递给它。假设你写了类似 A %>% mutate({...})
的东西。如果脚本 {...}
returns 一个数据框,那么它的列将直接在 A
中创建,或者如果它们共享相同的名称,则替换 A
中的现有列。所以你可以做
df %>% mutate({
cond <- x > 2
out <- tibble(.rows = n())
mapply(
\(var, true, false) out[[var]] <<- if_else(cond, true, false),
var = c("result", "auxiliary"),
true = list(x + y, "Calculation done"),
false = list(NA_integer_, NA_character_)
)
out
})
输出
# A tibble: 5 x 4
x y auxiliary result
<int> <int> <chr> <int>
1 1 1 NA NA
2 2 2 NA NA
3 3 3 Calculation done 6
4 4 4 Calculation done 8
5 5 5 Calculation done 10
我想创建一个新列,仅在它符合特定条件时记录它(此处 x > 2
),然后 直接 覆盖另一个现有列(此处auxiliary
) 对于条件 (x > 2
) 返回 TRUE 的这些行。
df <- tibble(x = 1:5, y = 1:5, auxiliary = NA)
# A tibble: 5 x 3
x y auxiliary
<int> <dbl> <lgl>
1 1 NA
2 2 NA
3 3 NA
4 4 NA
5 5 NA
我可以在 mutate()
内的两个不同调用中成功完成此操作:
df %>%
mutate(result = if_else(condition = x > 2,
true = x+y,
false = NA_real_),
auxiliary = if_else(condition = x > 2,
true = "Calculation done",
false = NA_character_))
# A tibble: 5 x 4
x y auxiliary result
<int> <dbl> <chr> <dbl>
1 1 NA NA
2 2 NA NA
3 3 Calculation done 6
4 4 Calculation done 8
5 5 Calculation done 10
但是有一些代码重复(condition = x > 2
),在更复杂的情况下,这使得阅读代码非常困难并且容易出错,尤其是在有多个条件时。
有没有办法通过不重复条件来简化上面的代码? :
- 创建新变量(
mutate()
) - 仅当条件匹配时才记录(
if_else
或case_when()
) - 仅当行的条件匹配时写入另一列的值。 (我被困在这里)
看起来像这样的东西:
df %>%
mutate(result = case_when(
x > 2 ~ x + y & auxiliary == "Calculation done", # we'd add the column reference here...
TRUE ~ NA_real & auxiliary = NA_character_))
非常感谢!来自 tidyverse 的任何解决方案都是理想的。
我建议将应该多次使用的条件保存为字符串,然后在代码中使用该字符串作为变量,例如:
condition <- "x>2"
df %>%
mutate(result = ifelse(eval(parse(text=condition)),
x+y,
NA),
auxiliary = ifelse(eval(parse(text=condition)),
"Calculation done",
NA))
请注意,我使用的是基本 ifelse 语句,以避免我必须在列中使用相同类型的限制(“dplyr::if_else 专门用于强制您使用相同的类型输入你的真假论点。”)。查看更多信息,例如Different behavior of if else statement and if_else.
您可以将条件的结果保存在列中并使用它来避免一次又一次地评估相同的条件。
library(dplyr)
df <- tibble(x = 1:5, y = 1:5)
df %>%
mutate(condition = x > 2,
result = if_else(condition,
true = x+y,
false = NA_integer_),
auxiliary = if_else(condition,
true = "Calculation done",
false = NA_character_))
# x y condition result auxiliary
# <int> <int> <lgl> <int> <chr>
#1 1 1 FALSE NA NA
#2 2 2 FALSE NA NA
#3 3 3 TRUE 6 Calculation done
#4 4 4 TRUE 8 Calculation done
#5 5 5 TRUE 10 Calculation done
可以实现您想要的那种抽象,但确实需要更多的设置。 mutate
其实比你想象的要灵活。您可以将脚本传递给它。假设你写了类似 A %>% mutate({...})
的东西。如果脚本 {...}
returns 一个数据框,那么它的列将直接在 A
中创建,或者如果它们共享相同的名称,则替换 A
中的现有列。所以你可以做
df %>% mutate({
cond <- x > 2
out <- tibble(.rows = n())
mapply(
\(var, true, false) out[[var]] <<- if_else(cond, true, false),
var = c("result", "auxiliary"),
true = list(x + y, "Calculation done"),
false = list(NA_integer_, NA_character_)
)
out
})
输出
# A tibble: 5 x 4
x y auxiliary result
<int> <int> <chr> <int>
1 1 1 NA NA
2 2 2 NA NA
3 3 3 Calculation done 6
4 4 4 Calculation done 8
5 5 5 Calculation done 10