Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 检查向量中与变量名对应的元素是否属于数据帧中的字符类_R_Function_Dataframe_Dplyr_Purrr - Fatal编程技术网

R 检查向量中与变量名对应的元素是否属于数据帧中的字符类

R 检查向量中与变量名对应的元素是否属于数据帧中的字符类,r,function,dataframe,dplyr,purrr,R,Function,Dataframe,Dplyr,Purrr,我正试图为我的功能建立一个安全锁销。 我希望它获取一个数据帧的输入和一个变量名向量来检查类。我想让它尝试强制任何无法指定字符的变量,发送警告,或者如果强制失败,停止进程 到目前为止,我得到的是: #Inputs varlist <- c("varA","varB","varC") df <- data.frame(matrix(ncol=4,nrow=0, dimnames=list(NULL, c("varA", "varB", "varC","varD")))) df$varA

我正试图为我的功能建立一个安全锁销。 我希望它获取一个数据帧的输入和一个变量名向量来检查类。我想让它尝试强制任何无法指定字符的变量,发送警告,或者如果强制失败,停止进程

到目前为止,我得到的是:

#Inputs
varlist <- c("varA","varB","varC")
df <- data.frame(matrix(ncol=4,nrow=0, dimnames=list(NULL, c("varA", "varB", "varC","varD"))))
df$varA <- as.character(df$varA)
df$varB <- as.character(df$varB)
df$varC <- as.factor(df$varC)
df$varD <- as.numeric(df$varD)

for(i in 1:length(varlist)){
   if(!(purrr::pmap(select(df, varlist[i]), ~is.character)==TRUE)){
        df$varlist[i] <- as.character(df$varlist[i])
        warning(paste0("Coercing variable", varlist[i], "to character"))
        stopifnot(is.character(df$varlist[i]))
 } 
}
有没有一个简单的方法可以做到这一点

预期产出

#output console warning
Warning: Coercing variable varC to character

#Manual checks
is.character(df$varA) == TRUE #included in varlist
is.character(df$varB) == TRUE #included in varlist
is.character(df$varC) == TRUE #included in varlist, coerced from factor to character
is.character(df$varD) == FALSE #not included in varlist



我有一些我认为可以在for循环中工作的东西。如果您的数据帧相当大并且有很多列,那么有一种方法可以应用它来加速它,但是这与您最初拥有的数据帧更接近

制作数据

varlist <- c("varA","varB","varC")
df <- data.frame(varA = letters[1:4],
                 varB = letters[11:14],
                 varC = letters[21:24],
                 varD = 1:4)
df$varA <- as.character(df$varA)
df$varB <- as.character(df$varB)
df$varC <- as.factor(df$varC)
df$varD <- as.numeric(df$varD)
使用
Map

更新以使用
Map
执行相同的操作,这是
apply的多变量版本:

char_function <- function(x, name){
  y <- as.character(x)
  if(!(is.character(x))){
    warning((paste("Coercing variable", name, "to character")))
  } 
  return(y)
}

df.char <- data.frame(Map(char_function, df[varlist], names(df[varlist])), stringsAsFactors = F)

char\u函数您的示例显示0行的
df
。。你的期望是什么output@akrun更新问题,包括控制台警告和肯定检查。映射通常用于并行迭代。您这样做是因为您正在迭代列和列名,但实际上并不需要这样做。(另外,
as.character
足够聪明,不会对已经是
character
的东西做任何事情——你不需要为此创建包装器。)你可以直接使用
lappy
df.char=data.frame(lappy(df,as.character),stringsafactors=F)
,或者如果就地修改
df[]=lappy(df,char_函数)
。这与OP的
varlist
df[varlist]=lappy(df[varlist],as.characteracter)配合得很好
哦,我完全没有意识到OP只想检查
varlist
中的某些变量。我包装了函数,以便它返回OP想要的警告。不知道如何在不编写明确包含它的函数的情况下执行此操作。但我将编辑响应以包含您的注释
    for(i in (1:ncol(df))[colnames(df) %in% varlist]){
    df[,i] <- as.character(df[,i])
  if(!(is.character(df[,i]))){
    warning(paste("Coercing variable", colnames(df)[i], "to character"))
  }
}
char_function <- function(x, name){
  y <- as.character(x)
  if(!(is.character(x))){
    warning((paste("Coercing variable", name, "to character")))
  } 
  return(y)
}

df.char <- data.frame(Map(char_function, df[varlist], names(df[varlist])), stringsAsFactors = F)