例如,
df1 = expand.grid(x1=1:2,x2=1:2,x3=1:2,x4=1:2,x5=1:2,x6=1:2) %>%
mutate(
x7 = sample(1:2,64,T),
y1 = rnorm(64)
)
df2 = expand.grid(x1=1:2,x2=1:2,x3=1:2,x4=1:2,x5=1:2,x6=1:2) %>%
mutate(
x7 = sample(1:2,64,T),
y2 = rnorm(64)
)
myfunc <- function(data){
data %>%
mutate(key = paste(x1,x2,x3,x4,x5,x6)) %>%
pull(key)
}
joined_df = df1 %>%
mutate(y3 = runif(64)) %>%
mutate(key=myfunc([some sort of expression referencing df1])) %>%
inner_join(
df2 %>%
mutate(y4 = runif(64)) %>%
mutate(key=myfunc([some sort of expression referencing df2]),
by='key'
)
本质上,我想避免必须从看起来像这样的函数重新创建数据框
myfunc_v2 <- function(data){
data %>%
mutate(key = paste(x1,x2,x3,x4,x5,x6))
}
尽管
myfunc_v2()
可以说更干净,但主要原因是我通常使用 rename_all()
等转换函数在格式不同的源中更改变量名称,但不想实际修改它们,主要是复制,因为我保留其中一个小标题的列名称格式,然后丢弃其他小标题。
解决方案很简单。
使用管道运算符
%>%
(通常使用 dplyr)时,您可以指定在函数中应使用它作用于参数的位置。
对于参数的 copy,您所需要做的就是将
(.)
放在您想要对象的位置,前提是它不在某个匿名函数内部(例如,使用 mutate_all(data, list(scaled=~scale(.), signed=sign(.))
。
解决方案看起来就像这样
joined_df = df1 %>%
mutate(y3 = runif(64)) %>%
mutate(key=myfunc((.)) %>%
inner_join(
df2 %>%
mutate(y4 = runif(64)) %>%
mutate(key=myfunc((.)),
by='key'
)
如果您使用 magrittr 管道
%>%
,@Max-Candocia 的解决方案可以正常工作,但如果您使用本机管道 |>
,则不行。在这种情况下,您可以使用 pick(everything())
来引用整个 tibble(或带有 tidyselect 表达式的列的子集,而不是所有内容)。
OP 的代码已损坏,所以这里是另一个例子:
library(dplyr)
iris |>
as_tibble() |>
mutate(sum = pick(where(is.numeric)) |>
apply(1, sum)
)
#> # A tibble: 150 × 6
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species sum
#> <dbl> <dbl> <dbl> <dbl> <fct> <dbl>
#> 1 5.1 3.5 1.4 0.2 setosa 10.2
#> 2 4.9 3 1.4 0.2 setosa 9.5
#> 3 4.7 3.2 1.3 0.2 setosa 9.4
#> 4 4.6 3.1 1.5 0.2 setosa 9.4
#> 5 5 3.6 1.4 0.2 setosa 10.2
#> 6 5.4 3.9 1.7 0.4 setosa 11.4
#> 7 4.6 3.4 1.4 0.3 setosa 9.7
#> 8 5 3.4 1.5 0.2 setosa 10.1
#> 9 4.4 2.9 1.4 0.2 setosa 8.9
#> 10 4.9 3.1 1.5 0.1 setosa 9.6
#> # ℹ 140 more rows
创建于 2024-03-13,使用 reprex v2.1.0