我嘗試為具有一個或多個列變數的自定義表撰寫一個函式。我對具有一個變數的表實作了這一點:
.
現在我嘗試實作一個函式來獲取一組變數的自定義表,例如均值和多串列。我的問題是將它們系結在一起。
這就是我所擁有的:
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 函式的初學者。
問候,本
uj5u.com熱心網友回復:
解決方案
首先,一個答案:purrr::map_dfr自動行系結它的結果,你應該像這樣指定它:
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
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/427729.html
上一篇:對串列之間的函式求和
下一篇:將標題添加到二維陣列
