R 在多个数据集上使用相同的函数并使用特定列

R 在多个数据集上使用相同的函数并使用特定列,r,function,loops,for-loop,R,Function,Loops,For Loop,我有8个数据集,我想应用一个函数将每个数据集的3列(var1、var2、var3)上小于5的任何数字转换为NA。我如何编写一个函数来高效、快速地完成它?我在Stack overflow上浏览了很多这样的问题,但是在使用特定列的地方我没有找到任何答案。我已经编写了要替换的函数,但不知道如何应用于所有数据集 Input: Data1 variable1 variable2 variable3 variable4 10 36 56 99 15

我有8个数据集,我想应用一个函数将每个数据集的3列(var1、var2、var3)上小于5的任何数字转换为NA。我如何编写一个函数来高效、快速地完成它?我在Stack overflow上浏览了很多这样的问题,但是在使用特定列的地方我没有找到任何答案。我已经编写了要替换的函数,但不知道如何应用于所有数据集

Input:
Data1
variable1 variable2 variable3 variable4
10           36        56        99
15           3         2         56
4            24        1         1

Expected output:
variable1 variable2 variable3 variable4
10           36         56        99
15           NA         NA        56
NA           24        NA         1

对另外7个数据集执行相同的操作

Input:
Data1
variable1 variable2 variable3 variable4
10           36        56        99
15           3         2         56
4            24        1         1

Expected output:
variable1 variable2 variable3 variable4
10           36         56        99
15           NA         NA        56
NA           24        NA         1

到目前为止,我已经在两个不同的列表中存储了所需的变量和数据集

var1=enquo(variable1)
var2=enquo(variable2)
var3=enquo(variable3)
Total=3


listofdfs=list()
listofdfs_1=list()
for(i in 1:8) {
  df=sym((paste0("Data",i)))
listofdfs[[i]]=df
  }

for(e in 1:Ttoal) {    
listofdfs[[e]]= eval(sym(paste0("var",e)))
}
所选列将通过此功能:

temp_1=function(x,h) {
  h=enquo(h)
  for(e in 1:Total) {    
  if(substr(eval(sym(paste0("var",e))),1,3)=="var") {
 y= x %>% mutate_at(vars(!!h), ~ replace(., which(.<=5),NA))
 return(y)
  }

}
}
temp_1=函数(x,h){
h=equo(h)
(e)在1:Total中{
如果(substr(eval)(sym(paste0(“var”,e))),1,3)=“var”){

y=x%>%mutate_at(vars(!!h),~replace(。这是问题的解决方案。
首先,创建一个测试数据集

createData <- function(Total = 3){
  numcols <- Total + 1
  set.seed(1234)
  for(i in 1:8){
    tmp <- replicate(numcols, sample(10, 20, TRUE))
    tmp <- as.data.frame(tmp)
    names(tmp) <- paste0("var", seq_len(numcols))
    assign(paste0("Data", i), tmp, envir = .GlobalEnv)
  }
}

createData()
我将介绍解决方案,一个基本R解决方案和一个
tidyverse
one解决方案。请注意,这两个解决方案都将使用仅用基本R编写的函数
temp_1

library(tidyverse)

temp_1 <- function(x, h){
  f <- function(v){
    is.na(v) <- v <= 5
    v
  }
  x[h] <- lapply(x[h], f)
  x
}

h <- grep("var[123]", names(df_list[[1]]), value = TRUE)

df_list1 <- lapply(df_list, temp_1, h)
df_list2 <- df_list %>% map(temp_1, h)

identical(df_list1, df_list2)
#[1] TRUE
库(tidyverse)

temp_1这里有一个简单的方法应该有效:

cols_to_edit = paste0("var", 1:3)
result_list = lapply(list_of_dfs, function(x) {
  x[cols_to_edit][x[cols_to_edit] < 5] = NA
  return(x)
})
cols_to_edit=paste0(“变量”,1:3)
结果列表=lappy(函数(x)的dfs列表){
x[cols_to_edit][x[cols_to_edit]<5]=NA
返回(x)
})

我假设您的起始数据在一个名为
list\u of_dfs
的列表中,所有数据帧中要编辑的列的名称都是相同的,并且您可以用这些名称构造一个字符向量
cols\u to\u edit

@MrFlick抱歉给您带来不便!我已经编辑了这个问题。@MrFlick抱歉,我已经编辑了!我的va变量名称在所有数据集中都是相同的,但将来可能会更改,因此我尝试使用like宏。将来的变量名称可以从variable3更改为variable4,因此我想使用宏。当我尝试编写代码时:cols_to_edit=eval(sym(paste0(“var”,1:3)))result=lappy(dfs的列表,函数(x){x[cols_to_edit][x[cols_to_edit]<5]=NA return(x)})它给出了错误:error in
*tmp*
[cols_to_edit]:类型为“symbol”的对象不是子可附加的是,所以我的代码可以工作,但是当您将其更改为
eval(sym())
时它就不工作了。为什么不创建字符串列名呢?看起来仍然是模块化的,但要简单得多。您可以将
cols_to_edit=0(“变量”,1:3)
to
cols\u to\u edit=paste0(“变量”,1:4)
同样容易——除了代码的其余部分也可以工作。但是var1可以类似于variable1。我不想硬编码它。将来如果var1类似于某个不同的名称,那么如果它不是硬编码的话就很容易了。因此我需要使用evalHello。很抱歉,我忘了提到我需要使用vars作为宏变量,这样当我它解析为Variable1、Variable2和Variable3。你能帮我一下吗?存储名称的变量h不能像你在代码中提到的那样工作。