利用dplyr中Cross()中的函数处理成对列
假设我有这样的数据。我希望为每个广告运行一个函数,与带下划线的数字配对,即AD1fun、AD2fun、AD3fun 而不是写作利用dplyr中Cross()中的函数处理成对列,r,function,dplyr,across,R,Function,Dplyr,Across,假设我有这样的数据。我希望为每个广告运行一个函数,与带下划线的数字配对,即AD1fun、AD2fun、AD3fun 而不是写作 set.seed(3) library(dplyr) x <- tibble(Measure = c("Height","Weight","Width","Length"), AD1_1= rpois(4,10), AD1_2= rpois(4,9),
set.seed(3)
library(dplyr)
x <- tibble(Measure = c("Height","Weight","Width","Length"),
AD1_1= rpois(4,10),
AD1_2= rpois(4,9),
AD2_1= rpois(4,10),
AD2_2= rpois(4,9),
AD3_1= rpois(4,10),
AD3_2= rpois(4,9))
表明
fun <- function(x,y){x-y}
dat %>%
mutate(AD1fun = fun(AD1_1,AD1_2),
AD2fun = fun(AD2_1,AD2_2),
...)
可用于生产
x_minus <- x %>%
mutate(fun(across(ends_with("_1"), .names = "{col}_minus"), across(ends_with("_2")))) %>%
rename_with(~ sub("_\\d+", "", .), ends_with("_minus"))
但是,如果我们要进行非操作功能
# A tibble: 4 x 10
Measure AD1_1 AD1_2 AD2_1 AD2_2 AD3_1 AD3_2 AD1_minus AD2_minus AD3_minus
<chr> <int> <int> <int> <int> <int> <int> <int> <int> <int>
1 Height 6 10 10 3 12 8 -4 7 4
2 Weight 8 9 13 6 14 7 -1 7 7
3 Width 10 9 11 5 12 8 1 6 4
4 Length 8 9 8 7 8 13 -1 1 -5
它将产生一个错误,因为引用
这个过程本质上意味着比较两个数据集:一个
变量以_1结尾,一个以_2结尾。因此,情况是一样的
作为dat%>%selectends\u与_1-dat%>%selectends\u与_2。
因为这些都是列表,你不能用这种方式比较它们
如果是这样的话,我们可以做些什么来包含一个使用cross的函数?我们可以在名称以_1结尾的列之间循环,然后使用cur_column来提取列名,将后缀部分替换为_2,获取值并将其用作当前列和来自_2的对应对的fun的参数
-输出
library(dplyr)
library(stringr)
x %>%
mutate(across(ends_with("_1"), ~
fun(., get(str_replace(cur_column(), "_1$", "_2"))), .names = "{.col}_case"))
library(purrr)
x %>%
select(-Measure) %>%
split.default(str_remove(names(.), "_\\d+$")) %>%
map_dfr(reduce, fun) %>%
rename_all(~ str_c(., "_case")) %>%
bind_cols(x, .)
-输出
library(dplyr)
library(stringr)
x %>%
mutate(across(ends_with("_1"), ~
fun(., get(str_replace(cur_column(), "_1$", "_2"))), .names = "{.col}_case"))
library(purrr)
x %>%
select(-Measure) %>%
split.default(str_remove(names(.), "_\\d+$")) %>%
map_dfr(reduce, fun) %>%
rename_all(~ str_c(., "_case")) %>%
bind_cols(x, .)
感谢您对三种不同方法的清晰解释。在第三种矢量化方法中,do.calldata.frame的用途是什么。提供我看到这样做会导致维度变得有点不确定,但我不明白为什么它会这样做。@aiorr从fun矢量化的输出是一个单列矩阵。因此,do.call data.frame用于确保列都是数据集中的常规列。i、 它将矩阵列展平为3列
# A tibble: 4 x 10
# Measure AD1_1 AD1_2 AD2_1 AD2_2 AD3_1 AD3_2 AD1_case AD2_case AD3_case
# <chr> <int> <int> <int> <int> <int> <int> <chr> <chr> <chr>
#1 Height 6 10 10 3 12 8 Disagree Disagree Disagree
#2 Weight 8 9 13 6 14 7 Agree Disagree Disagree
#3 Width 10 9 11 5 12 8 Agree Disagree Disagree
#4 Length 8 9 8 7 8 13 Agree Agree Disagree
x %>%
mutate(Vectorize(fun)(across(ends_with("_1"),
.names = "{col}_minus"), across(ends_with("_2"))))%>%
do.call(data.frame, .) %>%
rename_at(vars(contains('minus')),
~ str_extract(., 'AD\\d+_\\d+_minus'))
# Measure AD1_1 AD1_2 AD2_1 AD2_2 AD3_1 AD3_2 AD1_1_minus AD2_1_minus AD3_1_minus
#1 Height 6 10 10 3 12 8 Disagree Disagree Disagree
#2 Weight 8 9 13 6 14 7 Agree Disagree Disagree
#3 Width 10 9 11 5 12 8 Agree Disagree Disagree
#4 Length 8 9 8 7 8 13 Agree Agree Disagree