我有一个数据框架,其中包含一组收入变量和一组销售变量。我想创建一个新的变量集,它接受revenue变量的值,并检查它与哪个sales变量匹配,如果匹配,则返回相应的年份。
下面是一个简单的例子,说明我所拥有的和我正在努力实现的目标:
library(tidyverse)
library(rlang)
# Creating an example dataframe
df <- tibble(
revenues_1 = c(1, 3, 4),
revenues_2 = c(2, 4, 5),
sales_2005 = c(1, 2, 3),
sales_2006 = c(2, 3, 4),
sales_2007 = c(3, 4, 5)
)
# What I want to do:
# df <- df |>
# rowwise() |>
# mutate(
# year_1 = case_when(
# revenues_1 == sales_2005 ~ 2005,
# revenues_1 == sales_2006 ~ 2006,
# revenues_1 == sales_2007 ~ 2007,
# .default = NA
# ),
# year_2 = case_when(
# revenues_2 == sales_2005 ~ 2005,
# revenues_2 == sales_2006 ~ 2006,
# revenues_2 == sales_2007 ~ 2007,
# .default = NA
# )
# )
字符串
然而,如果我有很多年和很多收入变量,这是不可扩展的。我怎样才能使这更有效率?
一个想法是(不工作):
# Create a list of expressions for each year
years_exprs <- map(2005:2007, ~parse_expr(paste0("var == 'sales_", .x, "' ~ ", .x)))
# Use this list in a case_when statement
df <- df |>
rowwise() |>
mutate(across(starts_with("revenues_"), function(var) {
case_when(
!!!years_exprs,
.default = NA
)
}, .names = "year_{.col}")) |>
ungroup()
型
2条答案
按热度按时间5anewei61#
如果我理解正确的话,使用现有的代码,您可以使用
dplyr
的mutate
、across
和starts_with
,然后将函数放在命名列表中以创建新的变量。为了减少多年来创建单个
case_when
逻辑的工作量,您可以首先将rlang::parse_exprs()
与paste0
一起使用:字符串
然后使用
!!!
进行计算:型
输出:
型
注意:如果你的变量不一定都以“revenue”开头,你可以创建一个包含所需列的向量,不管它们是否共享相同的模式(这里是
mut_vars
),然后使用all_of()
:型
fafcakar2#
如果你绝对需要生成表达式,你可以这样做:
字符串
如果要使用分割切片操作符
!!!
,则需要为mutate
提供 named 表达式。这些名称将成为变量名称。你可以看到这个表达式在使用
rlang::qq_show
注入后是如何解析的:型
话虽如此,如果你能找到一种方法来实现@jpsmith提供的解决方案,那将是一个更好的实践。根据我的经验,当人们有宽格式的数据时,他们会以这种方式使用表达式。通常,转向更长的格式或使用可用的工具(如
across
)更容易。输出
型