I have a data frame in R with 100 variables (columns) and 100 observations (rows). Each row is a patient; the columns are different variables such as gender, height, body-mass index, etc. I know that I can easily compute summary estimates for all of my variables using the Hmisc library like so (note that I am using the veteran data set as an example).


First question

For this data set, there is a variable, trt, that can take two values. I would like to treat this as a categorical variable and stratify the describe function by this variable. That way I can know the summary information for all patients with a trt value of 1 and all patients with a trt value of 2.

Second question

I would like to quickly perform hypothesis tests to see if there is a significant difference between groups 1 and 2 for every other variable analyzed. For categorical variables, I'd like to automatically perform a Chi-sq test or Fisher's exact test. For continuous variables, I'd like to automatically perform a t test. And I want the code just to spit out some p values. Is there a way to do that?

Response to comment

My goal would be to use this code to easily compute what I would be putting into Table 1 of my manuscript, which will describe the baseline population characteristics. An example of such a table is here: http://www.ncbi.nlm.nih.gov/pmc/articles/PMC4281814/table/OFU040TB1/

My table would only have two columns. One for trt group 1, the other for trt group 2. And I would just report the means or median values, with a measure of dispersion like SD or IQR, then a p value for difference.

  • 3
    $\begingroup$ As asked, this is a pure programming question, which we can migrate to Stack Overflow for you. I wonder whether that would be a disservice, though, because when code just "spits out some p values" it is guaranteed they will be deceptive without further adjustment. I would like to suggest that before you ask a coding question, you consider asking the relevant statistical questions, such as "Is this procedure meaningful?" and "What might work better to accomplish X?" You would need to tell us what "X" is, of course--prediction, estimation, model building, variable selection, etc. $\endgroup$ – whuber Mar 10 '15 at 18:29
  • $\begingroup$ Thanks for your comment - I have updated my question accordingly. If you think it should be migrated please feel free - whatever you think is best. $\endgroup$ – Alexander Mar 10 '15 at 18:32
  • 1
    $\begingroup$ I'd strongly advise against doing a hundred hypothesis tests for what is intended to be descriptive purposes ("describe the characteristics"). Hypothesis tests are utterly unsuitable for such a descriptive task, and the p-values you obtain (which don't adjust for the effect of any other variables for starters), will mean little. Hypothesis tests - if they're used at all - should be used in a very considered way, on questions that are directly meaningful to the purpose of the study. $\endgroup$ – Glen_b -Reinstate Monica Mar 10 '15 at 21:59
  • 1
    $\begingroup$ I'm not an epidemiologist, but I can believe that. I am a psychologist, and I can verify that in psychology and in many other fields of science, there are a lot of bad conventions about how to do data analysis. That means that, unfortunately, one often needs to choose between being correct and making reviewers happy. How to make such a decision is a good question, but beyond the scope of a comment to answer. $\endgroup$ – Kodiologist Mar 10 '15 at 23:59
  • 1
    $\begingroup$ Alexandar, I agree that these p-values are necessary. I've worked on several (health economic and outcomes research) HEOR studies and nearly all report p-values to test for significant differences between cohorts at baseline. For all others interested, this is necessary in HEOR studies because this table helps determine which baseline characteristics should be controlled for in the following adjusted analyses. $\endgroup$ – AOGSTA Mar 11 '15 at 0:26

For your first question, just do

describe(subset(veteran, trt == 1))
describe(subset(veteran, trt == 2))


describe(veteran[veteran$trt == 1,])
    describe(veteran[veteran$trt == 2,])

For your second question, seeing as this is a data-analysis site and not a programming site, I'm going to simply tell you don't do that. The purpose of this table in your manuscript, if I understand correctly, is just to give the reader a sense of what the sample was like. As @whuber mentioned, it is not wise to naively perform the simplest hypothesis test possible for every variable, for several reasons, among them that you are describing the sample in this table, not trying to make inferences about any populations. If subjects were randomly assigned to groups, the populations are the same and therefore they must have the same population characteristics. If they weren't, and you want to investigate questions like "Are smokers taller than non-smokers?", that is a question that deserves a careful analysis in the main text as part of the study per se, rather than an afterthought tucked into the demographics table, and you should be picking and choosing questions to ask instead of throwing everything against the wall and seeing what sticks—at least if you're going to use a null-hypothesis significance-testing approach.


Good answer from Kodiologist. Just wanted to give my two cents.

Answer 1:

I would use by() function as I did below. The by function applies a function to each level of a factor vector.

the first argument below is the data set (veterans), the second is the factor level (trt), and the third is the function (describe).


Answer 2:

You can code a very flexible function that will take a vector as input, determine whether it is categorical or not, and apply the relevant test while conditionally applying fisher exact in case you get a warning with chi sq test.

Then you can use an apply family function to apply this flexible function to a list of variable names.

You can also not do this and use the functions chisq.test(), fisher.test(), or t.test() alone.

  • $\begingroup$ Great suggestion for answer two. Would you be able to point me in the direction to get started writing such a code? Or perhaps I should ask on StackOverFlow? Thanks again. $\endgroup$ – Alexander Mar 12 '15 at 18:42
  • 1
    $\begingroup$ Hi Alexander. It would involve making a user-defined function that will use conditional logic to determine which of the testing functions I listed above is appropriate for a given vector. I agree that you should post in stackoverflow for a more detailed answer and (if you're lucky) a code skeleton. I've seen such general functions in SAS and the three components are 1) user-defined function, 2) conditional statements, and 3) testing functions. $\endgroup$ – AOGSTA Mar 13 '15 at 0:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.