I am working with a WHO macro for transforming anthropometric parameters into Z-scores.
For the purpose of the question, calling the who2007
function requires us to give the name of the data frame and then only the name of the variables (columns) just like in ggplot function. The problem with this is, say if the column name is Age
entering argument=Age
is different from entering argument='Age'
. The former returns a double
but the latter returns a list
. I am assuming it is the difference of doing df$Age
vs df['Age']
.
If I have a vector of just the column names and I need to iterate over the same code using different columns each time, if I sequentially enter the respective entries of that character vector, the function throws an error since it encounters a list instead of a double internally. How do I circumvent this? One way I can think of is using the column-numbers or using any grep methods to identify the column numbers, but is there another better method?
ADDENDUM
Here is the function source code (a part of it which I think might explain the problem)
who2007 <- function(FileLab="Temp",FilePath="C:\\Documents and Settings",mydf,sex,age,weight,height,oedema=rep("n",dim(mydf)[1]),sw=rep(1,dim(mydf)[1])) {
#############################################################################
########### Calculating the z-scores for all indicators
#############################################################################
old <- options(warn=(-1))
sex.x<-as.character(get(deparse(substitute(mydf)))[,deparse(substitute(sex))])
age.x<-as.double(get(deparse(substitute(mydf)))[,deparse(substitute(age))])
weight.x<-as.double(get(deparse(substitute(mydf)))[,deparse(substitute(weight))])
height.x<-as.double(get(deparse(substitute(mydf)))[,deparse(substitute(height))])
if(!missing(oedema)) oedema.vec<-as.character(get(deparse(substitute(mydf)))[,deparse(substitute(oedema))]) else oedema.vec<-oedema
if(!missing(sw)) sw<-as.double(get(deparse(substitute(mydf)))[,deparse(substitute(sw))]) else sw<-as.double(sw)
sw<-ifelse(is.na(sw),0,sw)
sex.vec<-NULL
sex.vec<-ifelse(sex.x!="NA" & (sex.x=="m" | sex.x=="M" | sex.x=="1"),1,ifelse(sex.x!="NA" & (sex.x=="f" | sex.x=="F" | sex.x=="2"),2,NA))
age.vec<-age.x
height.vec<-height.x
oedema.vec<-ifelse(oedema.vec=="n" | oedema.vec=="N","n",ifelse(oedema.vec=="y" | oedema.vec=="Y","y","n"))
mat<-cbind.data.frame(age.x,as.double(sex.vec),weight.x,height.x,oedema.vec,sw,stringsAsFactors=F)
names(mat)<-c("age.mo","sex","weight","height","oedema","sw")
mat$cbmi<-mat$weight/((height.vec/100)^2)
mat$zhfa<-NULL
mat$fhfa<-NULL
mat$zwfa<-NULL
mat$fwfa<-NULL
mat$zbfa<-NULL
mat$fbfa<-NULL
#############################################################################
########### Calculating the z-scores for all indicators
#############################################################################
cat("Please wait while calculating z-scores...\n")
### Height-for-age z-score
mat<-calc.zhfa(mat,hfawho2007)
### Weight-for-age z-score
mat<-calc.zwei(mat,wfawho2007)
### BMI-for-age z-score
mat<-calc.zbmi(mat,bfawho2007)
#### Rounding the z-scores to two decimals
mat$zhfa<-rounde(mat$zhfa,digits=2)
mat$zwfa<-rounde(mat$zwfa,digits=2)
mat$zbfa<-rounde(mat$zbfa,digits=2)
#### Flagging z-score values for individual indicators
mat$fhfa<-ifelse(abs(mat$zhfa) > 6,1,0)
mat$fwfa<-ifelse(mat$zwfa > 5 | mat$zwfa < (-6),1,0)
mat$fbfa<-ifelse(abs(mat$zbfa) > 5,1,0)
if(is.na(mat$age.mo) & mat$oedema=="y") {
mat$fhfa<-NA
mat$zwfa<-NA
mat$zbfa<-NA
}
mat<-cbind.data.frame(mydf,mat[,-c(2:6)])
ADDENDUM 2
The script is also intended to be run by ultiple users, where modifying the source code for them might not be possible. Is there a way to not need to modify the function source code?