R函数到bind_rows另一个函数的结果
R function to bind_rows the results of another function
我尝试为带有一个或多个列变量的自定义 table 编写一个函数。我用一个变量实现了 tables:
.
现在我尝试实现一个函数来为一组变量获取自定义 table,例如均值和多列 table。我的问题是将它们绑定在一起。
这是我拥有的:
library(tidyverse)
## at first some example data:
dv1 <- c(1, 0, 1, 0, 1) # dependent variable 1
dv2 <- c(1, 0, 1, 1, 1) # dependent variable 2
iv1 <- c("m", "f", "f", "m", "m") # independent variable 1
iv2 <- c(30, 40, 30, 40, 40) # independent variable 2
iv3 <- c("b", "c", "b", "a", "a") # ...
DATA <- data_frame(iv1, iv2, iv3, dv1, dv2) # build data frame
# the help function
cross_fun <- function(.data, DV, IV = IVs, fn = ~ mean(.x)) {
df <- .data %>%
select(all_of({{ IV }}), {{ DV }}) %>%
mutate(var = "dv") %>% # here I would like to have the {{ DV }} Argument as values of var, but mutate(var = {{ DV }}) or mutate (var = quote(DV)) does'nt work
mutate(across(all_of({{IV}}), as.character)) # for using it in "names_from" in pivot_wider
LIST <- list() # define a list
for (i in 1:(ncol(df)-2)) { # -1 for the DV
LIST[[i]] <- df %>% select(i, {{ DV }}, var)
}
dt <- purrr::map(
.x = LIST,
.f = ~ tidyr::pivot_wider(.x, names_from = 1, values_from = 2, values_fn = fn)
) %>%
purrr::reduce(left_join, by ="var")
return(dt)
}
# What I can do
## simple custom table
DATA %>% cross_fun(dv1, IV = c('iv3', 'iv1', 'iv2'))
## or I use a set (IVs is standard in cross_fun) in multiple tables
IVs <- c('iv3', 'iv1', 'iv2')
DATA %>% cross_fun(dv2)
## I can change the Variables for the columns and the function
DATA %>%
cross_fun(dv2, IV = c('iv3', 'iv1', 'iv2'), fn = ~sum(.x))
## now I try to bind them together in a way, that I can use it later in another function
List_2 <- list()
## I could write it in a List_2 ...
List_2[[1]] <- DATA %>% cross_fun(dv1)
# ... for every variable ...
List_2[[2]] <- DATA %>% cross_fun(dv2)
# ... and bind the rows
List_2 %>%
bind_rows()
# here comes my Problem, it doesn't work in my try with for loop ...
for (i in c('dv1', 'dv2')) {
Liste2[[i]] <- DATA %>%
cross_fun(DATA[[i]])
}
# or with map
DATA %>%
map(.x = c(dv1:dv2), .f = ~cross_fun(.x)) %>% # the cross_fun-function for more than one dependent variable
bind_rows()
抱歉代码乱七八糟。我是 R 函数的初学者。
问候,本
解决方案
首先,一个答案:purrr::map_dfr
自动row-binds它的结果,你应该这样指定它:
map_dfr(c("dv1", "dv2"), cross_fun, .data = DATA)
# # A tibble: 2 x 8
# var b c a m f `30` `40`
# <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 dv 1 0 0.5 0.667 0.5 1 0.333
# 2 dv 1 0 1 1 0.5 1 0.667
批评
您的代码中存在一些问题,其中一些与传递不正确的参数有关。例如,您的 for
循环将 DATA[[i]]
传递给 DV
而不是简单地 i
;这会传递来自 DATA[["dv1"]]
的实际值向量,而不仅仅是名称 "dv1"
,这是您的函数所期望的。
以下解决了这个问题:
List_2 <- list()
# `i` is confusing because the loop iterates over characters, not integers;
# use something like `varname` instead
for (varname in c('dv1', 'dv2')) {
List_2[[varname]] <- DATA %>%
cross_fun(varname)
}
bind_rows(List_2)
# # A tibble: 2 x 8
# var b c a m f `30` `40`
# <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 dv 1 0 0.5 0.667 0.5 1 0.333
# 2 dv 1 0 1 1 0.5 1 0.667
您的 map
电话有两个问题。第一,您没有将 DATA
传递给 cross_function()
;您只是将 .x
传递给 .data
参数,而没有传递给其他参数。第二,您试图将 DV
作为符号而不是字符传递。虽然这是可能的,但它很棘手(并且尝试使用 map
遍历符号会使它变得更棘手),并且您的代码未设置为正确处理它。
以下解决了这个问题:
map(c("dv1", "dv2"), .f = ~ cross_fun(DATA, .x)) %>%
bind_rows()
# # A tibble: 2 x 8
# var b c a m f `30` `40`
# <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 dv 1 0 0.5 0.667 0.5 1 0.333
# 2 dv 1 0 1 1 0.5 1 0.667
我尝试为带有一个或多个列变量的自定义 table 编写一个函数。我用一个变量实现了 tables:
现在我尝试实现一个函数来为一组变量获取自定义 table,例如均值和多列 table。我的问题是将它们绑定在一起。
这是我拥有的:
library(tidyverse)
## at first some example data:
dv1 <- c(1, 0, 1, 0, 1) # dependent variable 1
dv2 <- c(1, 0, 1, 1, 1) # dependent variable 2
iv1 <- c("m", "f", "f", "m", "m") # independent variable 1
iv2 <- c(30, 40, 30, 40, 40) # independent variable 2
iv3 <- c("b", "c", "b", "a", "a") # ...
DATA <- data_frame(iv1, iv2, iv3, dv1, dv2) # build data frame
# the help function
cross_fun <- function(.data, DV, IV = IVs, fn = ~ mean(.x)) {
df <- .data %>%
select(all_of({{ IV }}), {{ DV }}) %>%
mutate(var = "dv") %>% # here I would like to have the {{ DV }} Argument as values of var, but mutate(var = {{ DV }}) or mutate (var = quote(DV)) does'nt work
mutate(across(all_of({{IV}}), as.character)) # for using it in "names_from" in pivot_wider
LIST <- list() # define a list
for (i in 1:(ncol(df)-2)) { # -1 for the DV
LIST[[i]] <- df %>% select(i, {{ DV }}, var)
}
dt <- purrr::map(
.x = LIST,
.f = ~ tidyr::pivot_wider(.x, names_from = 1, values_from = 2, values_fn = fn)
) %>%
purrr::reduce(left_join, by ="var")
return(dt)
}
# What I can do
## simple custom table
DATA %>% cross_fun(dv1, IV = c('iv3', 'iv1', 'iv2'))
## or I use a set (IVs is standard in cross_fun) in multiple tables
IVs <- c('iv3', 'iv1', 'iv2')
DATA %>% cross_fun(dv2)
## I can change the Variables for the columns and the function
DATA %>%
cross_fun(dv2, IV = c('iv3', 'iv1', 'iv2'), fn = ~sum(.x))
## now I try to bind them together in a way, that I can use it later in another function
List_2 <- list()
## I could write it in a List_2 ...
List_2[[1]] <- DATA %>% cross_fun(dv1)
# ... for every variable ...
List_2[[2]] <- DATA %>% cross_fun(dv2)
# ... and bind the rows
List_2 %>%
bind_rows()
# here comes my Problem, it doesn't work in my try with for loop ...
for (i in c('dv1', 'dv2')) {
Liste2[[i]] <- DATA %>%
cross_fun(DATA[[i]])
}
# or with map
DATA %>%
map(.x = c(dv1:dv2), .f = ~cross_fun(.x)) %>% # the cross_fun-function for more than one dependent variable
bind_rows()
抱歉代码乱七八糟。我是 R 函数的初学者。
问候,本
解决方案
首先,一个答案:purrr::map_dfr
自动row-binds它的结果,你应该这样指定它:
map_dfr(c("dv1", "dv2"), cross_fun, .data = DATA)
# # A tibble: 2 x 8
# var b c a m f `30` `40`
# <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 dv 1 0 0.5 0.667 0.5 1 0.333
# 2 dv 1 0 1 1 0.5 1 0.667
批评
您的代码中存在一些问题,其中一些与传递不正确的参数有关。例如,您的 for
循环将 DATA[[i]]
传递给 DV
而不是简单地 i
;这会传递来自 DATA[["dv1"]]
的实际值向量,而不仅仅是名称 "dv1"
,这是您的函数所期望的。
以下解决了这个问题:
List_2 <- list()
# `i` is confusing because the loop iterates over characters, not integers;
# use something like `varname` instead
for (varname in c('dv1', 'dv2')) {
List_2[[varname]] <- DATA %>%
cross_fun(varname)
}
bind_rows(List_2)
# # A tibble: 2 x 8
# var b c a m f `30` `40`
# <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 dv 1 0 0.5 0.667 0.5 1 0.333
# 2 dv 1 0 1 1 0.5 1 0.667
您的 map
电话有两个问题。第一,您没有将 DATA
传递给 cross_function()
;您只是将 .x
传递给 .data
参数,而没有传递给其他参数。第二,您试图将 DV
作为符号而不是字符传递。虽然这是可能的,但它很棘手(并且尝试使用 map
遍历符号会使它变得更棘手),并且您的代码未设置为正确处理它。
以下解决了这个问题:
map(c("dv1", "dv2"), .f = ~ cross_fun(DATA, .x)) %>%
bind_rows()
# # A tibble: 2 x 8
# var b c a m f `30` `40`
# <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 dv 1 0 0.5 0.667 0.5 1 0.333
# 2 dv 1 0 1 1 0.5 1 0.667