针对R中的多个数据帧,在函数内组合for循环和mutate

针对R中的多个数据帧,在函数内组合for循环和mutate,r,for-loop,dplyr,mutate,R,For Loop,Dplyr,Mutate,我希望我能对我的问题有所了解。基本上,我想在几个不同的数据集中创建相同的变量集,它们是基于离群值、抗议答案等的原始数据集的子集。。我尝试过很多事情,但我完全被难倒了 首先,我意识到使用evalpasse是违反建议的,然而,我不是最有效的编码者,这是为了我的目的。 无论如何,我的目标基本上是创建一组变量-X_3,X_4,X_5等,这是一组其他变量-z1,z2_1,z3_1等的年数x12。 对于这一点,我有下面的代码,当我单独将“data”放在每个数据集名称中时,这些代码都会起作用 编辑: 数据预期

我希望我能对我的问题有所了解。基本上,我想在几个不同的数据集中创建相同的变量集,它们是基于离群值、抗议答案等的原始数据集的子集。。我尝试过很多事情,但我完全被难倒了

首先,我意识到使用evalpasse是违反建议的,然而,我不是最有效的编码者,这是为了我的目的。 无论如何,我的目标基本上是创建一组变量-X_3,X_4,X_5等,这是一组其他变量-z1,z2_1,z3_1等的年数x12。 对于这一点,我有下面的代码,当我单独将“data”放在每个数据集名称中时,这些代码都会起作用

编辑: 数据预期

#what it looks like now
  responseid   z3_1 z4_1 z5_1
1          1  4.720 7.08   NA
2          2  1.180   NA 1.18
3          3  1.180   NA 1.18
4          4  2.596 3.54   NA
5          5 15.340   NA   NA
6          6  2.360   NA 2.36

#what i'd like it look like:
  responseid   z3_1 z4_1 z5_1    X_3  X_4  X_5
1          1  4.720 7.08   NA  56.640 84.96    NA
2          2  1.180   NA 1.18  14.160    NA 14.16
3          3  1.180   NA 1.18  14.160    NA 14.16
4          4  2.596 3.54   NA  31.152 42.48    NA
5          5 15.340   NA   NA 184.080    NA    NA
6          6  2.360   NA 2.36  28.320    NA 28.32

#dput
#original
structure(list(responseid = c(1L, 2L, 3L, 4L, 5L, 
6L), z3_1 = c(4.72, 1.18, 1.18, 2.596, 15.34, 2.36), z4_1 = c(7.08, 
NA, NA, 3.54, NA, NA), z5_1 = c(NA, 1.18, 1.18, NA, NA, 2.36),  class = "data.frame", row.names = c(NA, 6L))

#expected
structure(list(responseid = c(1L, 2L, 3L, 4L, 5L, 
6L), z3_1 = c(4.72, 1.18, 1.18, 2.596, 15.34, 2.36), z4_1 = c(7.08, 
NA, NA, 3.54, NA, NA), z5_1 = c(NA, 1.18, 1.18, NA, NA, 2.36), 
    X_3 = c(56.64, 14.16, 14.16, 31.152, 184.08, 28.32), X_4 = c(84.96, 
    NA, NA, 42.48, NA, NA), X_5 = c(NA, 14.16, 14.16, NA, NA, 
    28.32)), class = "data.frame", row.names = c(NA, 6L))
但我想对几个数据集执行此操作,因此我希望使用一个函数在每个df上运行

for (i in 3:9){
    X.varname <- paste0("X_",i)
    data <- data %>%
      mutate(
        !!X.varname := eval(parse(text=paste0("z", i, "_1")))*12
      )
  }
但是,当我尝试将其放入函数中,以便在数据帧列表上运行时,不会发生任何情况:

f.test <- function(data){
for (i in 3:9){
    X.varname <- paste0("X_",i)
    data <- data %>%
      mutate(
        !!X.varname := eval(parse(text=paste0("z", i, "_1")))*12
      )
  }
}
有人知道为什么会这样吗?
这是我关于StackOverflow的第一个问题,如果有任何格式错误,我深表歉意

由于将数据分配给函数的数据参数,因此不会发生任何事情,函数的数据与全局环境中的数据不同。您可以使用assigndata、YourAssignedValue、envir=.GlobalEnv或使用深度赋值操作由于函数不返回任何内容,因此不会发生任何事情。通常不需要在R中显式返回某些内容,因为R会自动返回最后一个对象。但这是一个for循环,意味着它什么也不返回

要避免此问题,只需指定函数应返回的内容,即数据:

此外,由于需要对多个数据帧执行此操作,您可以使用@koenniem suggestion来使用purrr::map。将每个数据帧放入列表中,并将该函数应用于列表中的每个元素:

library(purrr)
df2 <- df %>% mutate_at(vars(-responseid), ~.+4)

df_t <- list(df, df2)

df_t %>% 
  map_df(my_fun)
#>    responseid   z3_1  z4_1 z5_1     X_3    X_4   X_5
#> 1           1  4.720  7.08   NA  56.640  84.96    NA
#> 2           2  1.180    NA 1.18  14.160     NA 14.16
#> 3           3  1.180    NA 1.18  14.160     NA 14.16
#> 4           4  2.596  3.54   NA  31.152  42.48    NA
#> 5           5 15.340    NA   NA 184.080     NA    NA
#> 6           6  2.360    NA 2.36  28.320     NA 28.32
#> 7           1  8.720 11.08   NA 104.640 132.96    NA
#> 8           2  5.180    NA 5.18  62.160     NA 62.16
#> 9           3  5.180    NA 5.18  62.160     NA 62.16
#> 10          4  6.596  7.54   NA  79.152  90.48    NA
#> 11          5 19.340    NA   NA 232.080     NA    NA
#> 12          6  6.360    NA 6.36  76.320     NA 76.32

嗨@Meg,欢迎来到StackOverflow,你能提供一个更清晰的例子来说明你在做什么吗?数据帧的简化版本使用dputdata和预期输出。Thnks,我现在已经完成了!所以我尝试了这个方法,但是使用GlobalEnvir和assign只会导致数据帧之外的变量,当我需要在5个数据帧中创建相同的变量时,这是没有帮助的…我知道你现在想要做什么了。我已更新我的答案。我将尝试数据[[X.varname]]%transmute!!X.varname:=evalparsetext=paste0z,i,_1*12在f.test中。用str写的不错_*
f.test <- function(data){
  for (i in 3:5){
    X.varname <- paste0("X_",i)
    data <- data %>%
      mutate(
        !!X.varname := eval(parse(text=paste0("z", i, "_1")))*12
      )
  }
  return(data)
}
library(dplyr)
library(stringr)


my_fun <- function(data) {
  data %>% 
    mutate_at(vars(starts_with("z")), .funs = list(TBC=~.*12)) %>% 
    rename_at(vars(ends_with('TBC')), .funs = ~{.x %>% str_extract('\\d') %>% str_c('X_', .)})
}
library(purrr)
df2 <- df %>% mutate_at(vars(-responseid), ~.+4)

df_t <- list(df, df2)

df_t %>% 
  map_df(my_fun)
#>    responseid   z3_1  z4_1 z5_1     X_3    X_4   X_5
#> 1           1  4.720  7.08   NA  56.640  84.96    NA
#> 2           2  1.180    NA 1.18  14.160     NA 14.16
#> 3           3  1.180    NA 1.18  14.160     NA 14.16
#> 4           4  2.596  3.54   NA  31.152  42.48    NA
#> 5           5 15.340    NA   NA 184.080     NA    NA
#> 6           6  2.360    NA 2.36  28.320     NA 28.32
#> 7           1  8.720 11.08   NA 104.640 132.96    NA
#> 8           2  5.180    NA 5.18  62.160     NA 62.16
#> 9           3  5.180    NA 5.18  62.160     NA 62.16
#> 10          4  6.596  7.54   NA  79.152  90.48    NA
#> 11          5 19.340    NA   NA 232.080     NA    NA
#> 12          6  6.360    NA 6.36  76.320     NA 76.32