Create function using table and dim

Hello,
I'm trying to write a simple function but I failed. I know It isn't very complicated, but I couldn't fix my code. This is the code:

dfeze=function(x,y) {

nam1=paste(paste(y,"id_d",sep="$"),"[",paste(y,x,sep="$"),"==1","]",sep="")

nam2=paste(paste(y,"strat",sep="$"),"[",paste(y,x,sep="$"),"==1","]",sep="")

dim(table(as.formula(nam1,nam2)))[1]-dim(table(as.formula(nam1,nam2)))[2]
}

As you can see, I am using strings in order enter that text in the table function.

The idea is to tabulate some result employing the 2 variables (id_d and strat), in reference to the data frame defined by "y".

The condition I am entering inside the table function is based on the value equal to 1 for the variable "x". After all that, I just extract the result from the subtraction of rows and column from this simple tabulate. However, I receive the message:

Error in formula.default(eval(parse(text = x, keep.source = FALSE)[[1L]])) : 
  invalid formula

Can you guide me?
Again, the idea in the future is entering the data frame and the variable that is equal to 1 in the function. A simple idea, but beyond my programming knowledge I am afraid.

Hi @jfca283. I just guess what you want to do something like this. If not, please explain your idea in more details and share some sample data.

dfeze <- function(x, y) {
  df <- eval(parse(text = paste0(y, "[", y, "$", x, "==1, c('id_d', 'strat')]")))
  tab <- table(df)
  dim(tab)[1] - dim(tab)[2]
}
1 Like

Thanks raytong. The eval, parse, and text function worked flawless.
However, I realised that I can't use the function I designed with lapply.
I mean, use a list of variables and apply the "dfeze" fx.
I think I programmed something too rigid.
What do you recommend me in order to be able to combine list of variables and the program I declared?
Thanks for your time and interest.

@jfca283. Can you share some sample data and the code that you use the map function.

data("iris")
dim(table(iris$Petal.Width[iris$Petal.Width==3],iris$Species[iris$Petal.Width==3]))[1]-dim(table(iris$Petal.Width[iris$Petal.Width==3],iris$Species[iris$Petal.Width==3]))[2]

That's the idea. I mean, just declaring the x and y in tab(x,y) , and specificy a third vector to use as filter. Here I used only one value (3), but what if I would want the whole vector Petal.Width to be evaluated?

Imagine the example above but using a big data base. I did it using a loop with for ...but tha't not the point in R.

I hope the example provided is enough to understand my issue. My apologies if I am not still clear in what I'm asking for.
Thanks

I impressed myself that I figured this out....

data("iris")

get_dim_diff <- function(df, cond_var, id_var, cond_val = NA,pi = FALSE) {
  cvar <- substitute(cond_var)
  ivar <- substitute(id_var)
  id_var <- substitute(Species)

  if(anyNA(cond_val)){ # assume if NA is part of the filtering condition, we dont want to filter
    c1 <- df[[cvar]]
    c2 <- as.character(df[[ivar]])
  } else {
    c1 <- df[[cvar]][df[[cvar]] %in% cond_val]
    c2 <- as.character(df[[ivar]][df[[cvar]] %in% cond_val]) # table gives odd results on factors when 0 
#observations match the filter, table will still show the x number of  levels with 0 counts on them 
# as character strings this doesnt happen
  }
  myt <- table(c1, c2)
  if(pi)
    print(myt)
  myd <- dim(myt)
  cat("Dimensions : ", myd, "\n")

  myd_dif <- myd[[1]] - myd[[2]]
  return(myd_dif)
}

get_dim_diff(iris, Petal.Width, Species, 1.4)
get_dim_diff(iris, Petal.Width, Species, .6)
get_dim_diff(iris, Petal.Width, Species, c(.6, 1.4)) # get both .6 and 1.4 values
get_dim_diff(iris, Petal.Width, Species)  # get all values

#set p flag to print the table that we get the dimensions of
get_dim_diff(iris, Petal.Width, Species, c(.6, 1.4),p=TRUE)

@jfca283. Are you mean something like follow.

x <- function(y) {
 data("iris")
 dim(table(iris$Petal.Width[iris$Petal.Width %in% y],iris$Species[iris$Petal.Width %in% y]))[1]-dim(table(iris$Petal.Width[iris$Petal.Width %in% y],iris$Species[iris$Petal.Width %in% y]))[2]
}

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.