1

I want to create a for loop in R, but it should depend on the last letter in 17 variables, and I have trouble finding out how to make the function see the variable name as a string.

The code I have now:

fisher.test(table( data.family$proband.unrelated, data.family$q_81_SQ00a)) 
fisher.test(table( data.family$proband.unrelated, data.family$q_81_SQ00b)) 
fisher.test(table( data.family$proband.unrelated, data.family$q_81_SQ00c)) 

As you can see, i just keep on repeating the code for each variable from the letter a to r, so i want to create a for loop, which can change the last letter of the variable q_81_SQ00a to the letters a-r.

for (i in c('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'r')) {

  fisher.test(data.family$proband.unrelated, data.family$q_81_SQ00'i'))  

}

I get the warning "unexpected symbol" for several places in the code. Thanks in advance!

Julie Ravn
  • 35
  • 3
  • Can you post a minimal reproducible example with data? I think there are better ways to do this in R than using a for loop, e.g. dplyr or data.table using groups (group_by or by). – Kristoffer Winther Balling Mar 30 '17 at 09:24

2 Answers2

1

You have to paste the letter to the variable name to get a character string, and then select the desired variable using the [] operator. Another hint: the letters constant in R contains letters from a to z.

Here is a solution:

for (i in letters[1:18]) {
  fisher.test(data.family["proband.unrelated"],
              data.family[paste0("q_81_SQ00", i)])  
}
jlesuffleur
  • 1,113
  • 1
  • 7
  • 19
  • Thanks! I've tried to run it, but i get the warning: 'x' and 'y' must have the same length – Julie Ravn Mar 30 '17 at 08:46
  • @JulieRavn that has nothing to do with the provided code but is all because (at least) one of your `q_81_SQ00` elements from the `data.family` differ in length from the `proband.unrelated` one. Fisher's test requires the length of `x` and `y` to be equal. – Therkel Mar 30 '17 at 10:35
  • Thanks @Therkel! You were right - two of the 17 variables had the option '3' instead of just '1' and '2'. But i still get an error (sorry, i'm a newbie in R!): " 'x' must have at least 2 rows and columns". And i've checked - there are two outcomes for each variable now. – Julie Ravn Mar 30 '17 at 11:16
0

By the comments, it seems you have some trouble with some of the Fisher tests. To see which go right and wrong, you could add the try function around the Fisher test.

lapply(letters[1:18], function(x){
    try(fisher.test(table(data.family$proband.unrelated,
                data.family[[paste0("q_81_SQ00", x)]])))
})
Therkel
  • 1,379
  • 1
  • 16
  • 31
  • The original code that you implicitly stated worked, included a `table` call while your loop attempt did not. I have kept that call although that is mere guesswork since I do not know what your data looks like. Perhaps you could add a `str(data.family)` to the bottom of your question? – Therkel Mar 30 '17 at 11:48
  • That worked for me! All the p values i get from your code is the same as when i run fishers test seperate for each variable - thanks! I think it was the lapply, can't see what else. – Julie Ravn Mar 30 '17 at 11:52
  • When using the `lapply`, we make the call inside a function. We can then use `try`, which allows us to run through the code even if some of the elements cause errors. [You could circumvent the issue in a `for` loop also](http://stackoverflow.com/q/14748557/3560695), however the use of `lapply` just conveniently puts the results in a combined list, I think. – Therkel Mar 30 '17 at 12:06