-2

I wrote a function for one of my regular tasks. I will just try to replicate my issue. Below is a random sample of how my data looks like. its an output of the function dput(mydataframe)

structure(list(respid = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), ssd = c(0, 
225, 236, 0, 221, 0, 0, 269, 265, 0), tea = c(228, 0, 269, 0, 
258, 241, 0, 222, 0, 256), juice = c(0, 236, 0, 236, 236, 0, 
236, 225, 242, 296), vad = c(236, 235, 0, 235, 235, 0, 235, 258, 
0, 236), energy = c(0, 235, 236, 235, 0, 236, 235, 0, 236, 0)), .Names = c("respid", 
"ssd", "tea", "juice", "vad", "energy"), row.names = c(NA, -10L
), class = c("tbl_df", "tbl", "data.frame"))

now, my objective is to write a function to filter out the non-zero rows in 'ssd' column. Then it would look like this

non-zero

I wrote the below function in R

SoT <- function(df,key) {
  df2 <- df %>% dplyr::filter(key > 0)
  df3 <- janitor::adorn_totals(df2, where = "row")
  df4 <- tail(df3,1) %>% janitor::adorn_percentages(denominator = "row") %>% janitor::adorn_pct_formatting()
  return(df4)
}

my desired output is just the percentage of the summation of the column totals (after filtering for ssd > 0). In the above function, I am just giving the function 2 inputs. 1 is the dataframe and the other is the 'variable name' that I want to filter. I am calling the function like this:

SoT(df1, "ssd")

My desired result in the below pic is the one in green, but I am getting the one in yellow.

enter image description here

This means that the 'filter function' in the code doesn't work. But everything is working fine if I use it simply line by line instead of wrapping inside a function. Any suggestions ?

I haven't removed the images (just for your reference), but I have made the data and code reproducible as suggested.

  • 3
    Please learn how to make a *reproducible* question. This includes things like: (1) either name non-base packages or include code for non-standard functions (e.g., `adorn_totals`), or don't use them; (2) don't provide images of code or data, it cannot be copied or searched, breaks screen readers, and may not fit on all mobile devices (https://meta.stackoverflow.com/a/285557/3358272); (3) provide sample data in a more consumable format, such as the output from `dput(head(x))` (for desired, too) (https://stackoverflow.com/questions/5963269). – r2evans Dec 24 '18 at 05:56
  • 1
    `0` may not really be `0`. Could be 0.000001` and that result might occur. Can't really tell because you are only offering pictures, not data. – IRTFM Dec 24 '18 at 07:10
  • I understand, i ll revamp the question – Aravindh Rajan Dec 24 '18 at 11:59

1 Answers1

1

When you program with dplyr, for instance specifying a key to filter with, you need to clarify from which environment you want key to be defined.

https://dplyr.tidyverse.org/articles/programming.html

In this case, to use the key you're passing in your function, you need two steps:

1) quote the key argument using enquo()

2) unquote it using !!

Together, these tell dplyr that you want to use the key that you've passed into the function, and not any other key that might be defined outside your function.

SoT <- function(df,key) {
  key_quoted <- enquo(key)
  df2 <- df %>% dplyr::filter(!!key_quoted > 0)
  df3 <- janitor::adorn_totals(df2, where = "row")
  df4 <- tail(df3,1) %>% janitor::adorn_percentages(denominator = "row") %>% janitor::adorn_pct_formatting()
  return(df4)
}

SoT(df1, ssd)
# respid   ssd   tea juice   vad energy
# Total 28.0% 17.3% 21.6% 16.8%  16.3%
Jon Spring
  • 55,165
  • 4
  • 35
  • 53