英文:
How can I create colum names in a custom function, pass it to dplyr's select and use purrr's pmap to recycle the custom function?
问题
以下代码应该创建一个名为df_test_purrr
的列表,其中包含两个数据框。这两个数据框应该分别包含列vs
和vs_txt
以及am
和am_txt
。
作为第一步,函数fn_test
接受一个数据框的参数dta
和一个列的参数col
。直接使用参数dta = df_mtcars, col = expr(vs)
调用该函数会创建预期的数据框df_test
。
# 函数库
library(dplyr)
library(purrr)
# 数据
df_mtcars <- mtcars %>%
dplyr::mutate(vs_txt = dplyr::case_when(vs == 1 ~ "ABC", T ~ "XYZ"),
am_txt = dplyr::case_when(am == 1 ~ "TTT", T ~ "BBB"))
# 用于单列的函数
fn_test <- function(dta, col) {
{{dta}} %>%
dplyr::select({{col}}, as.name( paste0({{col}}, "_txt") ))
}
# 单列的结果
df_test <- fn_test( dta = df_mtcars, col = expr(vs) )
# Purrr
fn_test_purrr <- function() {
purrr::pmap(list(
list(df_mtcars, df_mtcars),
list(expr(vs), expr(am))
), fn_test )
}
df_test_purrr <- fn_test_purrr()
定义和调用函数fn_test_purrr
会出现错误:
Error in `instrument_base_errors()`:
! object 'vs' not found
Caused by error:
! object 'vs' not found
Run `rlang::last_error()` to see where the error occurred.
如何使函数正常工作?
请注意,在我的实际应用程序中,函数fn_test_purrr
具有超过两个参数,因此我必须使用purrr的pmap
(我猜测)。
英文:
The following code is supposed to create a list, df_test_purrr
, with two dataframes. The two dataframes should contain the columns vs, vs_txt
and am, am_txt
, respectively.
As a first step, the function fn_test
takes an argument for a dataframe, dta
, and an argument for a column, col
. Using the function directly with the argument dta = df_mtcars, col = expr(vs)
creates the dataframe df_test
as expected.
# Libaries
library(dplyr)
library(purrr)
# Data
df_mtcars <- mtcars %>%
dplyr::mutate(vs_txt = dplyr::case_when(vs == 1 ~ "ABC", T ~ "XYZ"),
am_txt = dplyr::case_when(am == 1 ~ "TTT", T ~ "BBB"))
# Function for one column
fn_test <- function(dta, col) {
{{dta}} %>%
dplyr::select( {{col}}, as.name( paste0( {{col}}, "_txt") ) )
}
# Result for one column
df_test <- fn_test( dta = df_mtcars, col = expr(vs) )
# Purrr
fn_test_purrr <- function() {
purrr::pmap(list(
list(df_mtcars, df_mtcars),
list(expr(vs), expr(am))
), fn_test )
}
df_test_purrr <- fn_test_purrr()
Defining and calling the function fn_test_purrr
gives the error:
Error in `instrument_base_errors()`:
! object 'vs' not found
Caused by error:
! object 'vs' not found
Run `rlang::last_error()` to see where the error occurred.
How can I make the function work?
Please note that the function fn_test_purrr
has more than two arguments in my real-world application such that I must use purrr's pmap
(I guess).
答案1
得分: 1
请尝试以下代码:
# 用于单列的函数
fn_test <- function(dta, col) {
col2 <- paste0(col,'_txt')
col2 <- col2[col2!='c_txt']
dta %>%
dplyr::select( {{col}}, col2)
}
# 单列的结果
df_test <- fn_test( dta = df_mtcars, col = expr(c(vs,am)) )
# 输出
vs am vs_txt am_txt
Mazda RX4 0 1 XYZ TTT
Mazda RX4 Wag 0 1 XYZ TTT
Datsun 710 1 1 ABC TTT
Hornet 4 Drive 1 0 ABC BBB
Hornet Sportabout 0 0 XYZ BBB
Valiant 1 0 ABC BBB
Duster 360 0 0 XYZ BBB
Merc 240D 1 0 ABC BBB
Merc 230 1 0 ABC BBB
Merc 280 1 0 ABC BBB
Merc 280C 1 0 ABC BBB
Merc 450SE 0 0 XYZ BBB
Merc 450SL 0 0 XYZ BBB
Merc 450SLC 0 0 XYZ BBB
Cadillac Fleetwood 0 0 XYZ BBB
Lincoln Continental 0 0 XYZ BBB
Chrysler Imperial 0 0 XYZ BBB
Fiat 128 1 1 ABC TTT
Honda Civic 1 1 ABC TTT
Toyota Corolla 1 1 ABC TTT
Toyota Corona 1 0 ABC BBB
Dodge Challenger 0 0 XYZ BBB
AMC Javelin 0 0 XYZ BBB
Camaro Z28 0 0 XYZ BBB
Pontiac Firebird 0 0 XYZ BBB
Fiat X1-9 1 1 ABC TTT
Porsche 914-2 0 1 XYZ TTT
Lotus Europa 1 1 ABC TTT
Ford Pantera L 0 1 XYZ TTT
Ferrari Dino 0 1 XYZ TTT
Maserati Bora 0 1 XYZ TTT
Volvo 142E 1 1 ABC TTT
英文:
Could you please try the below code
# Function for one column
fn_test <- function(dta, col) {
col2 <- paste0(col,'_txt')
col2 <- col2[col2!='c_txt']
dta %>%
dplyr::select( {{col}}, col2)
}
# Result for one column
df_test <- fn_test( dta = df_mtcars, col = expr(c(vs,am)) )
#output
vs am vs_txt am_txt
Mazda RX4 0 1 XYZ TTT
Mazda RX4 Wag 0 1 XYZ TTT
Datsun 710 1 1 ABC TTT
Hornet 4 Drive 1 0 ABC BBB
Hornet Sportabout 0 0 XYZ BBB
Valiant 1 0 ABC BBB
Duster 360 0 0 XYZ BBB
Merc 240D 1 0 ABC BBB
Merc 230 1 0 ABC BBB
Merc 280 1 0 ABC BBB
Merc 280C 1 0 ABC BBB
Merc 450SE 0 0 XYZ BBB
Merc 450SL 0 0 XYZ BBB
Merc 450SLC 0 0 XYZ BBB
Cadillac Fleetwood 0 0 XYZ BBB
Lincoln Continental 0 0 XYZ BBB
Chrysler Imperial 0 0 XYZ BBB
Fiat 128 1 1 ABC TTT
Honda Civic 1 1 ABC TTT
Toyota Corolla 1 1 ABC TTT
Toyota Corona 1 0 ABC BBB
Dodge Challenger 0 0 XYZ BBB
AMC Javelin 0 0 XYZ BBB
Camaro Z28 0 0 XYZ BBB
Pontiac Firebird 0 0 XYZ BBB
Fiat X1-9 1 1 ABC TTT
Porsche 914-2 0 1 XYZ TTT
Lotus Europa 1 1 ABC TTT
Ford Pantera L 0 1 XYZ TTT
Ferrari Dino 0 1 XYZ TTT
Maserati Bora 0 1 XYZ TTT
Volvo 142E 1 1 ABC TTT
答案2
得分: 1
请检查更新后的代码,该代码返回包含两个数据框的列表。
df_mtcars <- mtcars %>%
dplyr::mutate(vs_txt = dplyr::case_when(vs == 1 ~ "ABC", T ~ "XYZ"),
am_txt = dplyr::case_when(am == 1 ~ "TTT", T ~ "BBB"))
fn_test <- function(dta, col) {
col2 <- paste0(col,'_txt')
col2 <- col2[col2!='c_txt']
if (length(col)==1){
len=1
col2 <- paste0(col,'_txt')
} else if(length(col)>1){
len <- length(col)-1
}
my.list <- list()
for(i in 1:len){
colx <- paste0({{col}})[i+1]
colx2 <- col2[i]
dat <- dta %>%
dplyr::select( {{colx}}, colx2)
my.list[[i]] <- dat
}
return(my.list)
}
# 一个列的结果
mylist <- fn_test( dta = df_mtcars, col = expr(c(vs,am)) )
df1 <- as.data.frame(mylist[1])
df2 <- as.data.frame(mylist[2])
这是代码的翻译部分,不包括问题的回答。
英文:
Please check updated code which returns the list with 2 dataframes
df_mtcars <- mtcars %>%
dplyr::mutate(vs_txt = dplyr::case_when(vs == 1 ~ "ABC", T ~ "XYZ"),
am_txt = dplyr::case_when(am == 1 ~ "TTT", T ~ "BBB"))
fn_test <- function(dta, col) {
col2 <- paste0(col,'_txt')
col2 <- col2[col2!='c_txt']
if (length(col)==1){
len=1
col2 <- paste0(col,'_txt')
} else if(length(col)>1){
len <- length(col)-1
}
my.list <- list()
for(i in 1:len){
colx <- paste0({{col}})[i+1]
colx2 <- col2[i]
dat <- dta %>%
dplyr::select( {{colx}}, colx2)
my.list[[i]] <- dat
}
return(my.list)
}
# Result for one column
mylist <- fn_test( dta = df_mtcars, col = expr(c(vs,am)) )
df1 <- as.data.frame(mylist[1])
df2 <- as.data.frame(mylist[2])
答案3
得分: 0
以下是您要翻译的内容:
对于那些感兴趣的人,我提出了一种不同的方法,也适用于我的目的:
库
library(dplyr)
library(purrr)
数据
df_mtcars <- mtcars %>%
dplyr::mutate(vs_txt = dplyr::case_when(vs == 1 ~ "ABC", T ~ "XYZ"),
am_txt = dplyr::case_when(am == 1 ~ "TTT", T ~ "BBB"))
用于一个列的函数
fn_test <- function(dta, var) {
dta %>%
dplyr::select( {{var}} )
}
函数调用
test <- fn_test(dta = df_mtcars, var = c("vs", "vs_txt"))
Purrr
fn_test_purrr <- function() {
purrr::pmap(
list(
list(df_mtcars, df_mtcars),
list(c("vs", "vs_txt"), c("am", "am_txt"))
), fn_test
)
}
函数调用
test_purrr <- fn_test_purrr()
结果
test_purrr[[1]]
test_purrr[[2]]
英文:
For those who are interested, I came up with a different approach that also works for my purpose:
# Libaries
library(dplyr)
library(purrr)
# Data
df_mtcars <- mtcars %>%
dplyr::mutate(vs_txt = dplyr::case_when(vs == 1 ~ "ABC", T ~ "XYZ"),
am_txt = dplyr::case_when(am == 1 ~ "TTT", T ~ "BBB"))
# Function for one column
fn_test <- function(dta, var) {
dta %>%
dplyr::select( {{var}} )
}
# Function call
test <- fn_test(dta = df_mtcars, var = c("vs", "vs_txt"))
# Purrr
fn_test_purrr <- function() {
purrr::pmap(
list(
list(df_mtcars, df_mtcars),
list(c("vs", "vs_txt"), c("am", "am_txt"))
), fn_test
)
}
# Function call
test_purrr <- fn_test_purrr()
# Results
test_purrr[[1]]
test_purrr[[2]]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论