0

I am trying to make a loop so I can have in a list the results that come out of the loop below.

As you can see, my data is taken out from the 10 electrodes of two individuals and I would like to compare every pair of electrodes and model a generalised linear model out of it, and this is where the nested loop comes handy. I used the instructions in Populating a data frame in R in a loop thread and there goes my code. The problem is, it does not write more than one line, it does not iterate.

dfnew <- as.data.frame(matrix(NA,0,4))
x <- c("elec1", "elec2", "estimate", "pvalue")
colnames(dfnew) <- x

for (i in 1:100){ #total numbers of coincidences between the electrodes from both individuals
for (j in 1:10){ #electrodes from individual 1
  for (k in 1:10){ #electrodes from individual 2

A <- subset(dyad_data, elec1 == j & elec2 == k)

B1 <- glm(response ~ dyad , data = A, family=Gamma(link = "inverse"))

dfnew[i,1] <- print(j) #it prints the identifier of electrode from individual 1
dfnew[i,2] <- print(k) #it prints the identifier of electrode from individual 2
dfnew[i,3] <- coef(summary(B1))[2, 3]
dfnew[i,4] <- coef(summary(B1))[2, 4]


}}}

The problem is the outcome seems to override previous line and it does not add a row but it stays in the same line.

This is how my A subset looks like with the electrode 1 from individual 1 and electrode 1 of individual 2, so you can have a look of my type of data:

> head(A)
     Elec1 Elec2 Dyad response
187  1     1     1    0.09312585
188  1     1     2    0.09561456
189  1     1     3    0.03530233
2374 1     1     4    0.08787908
2375 1     1     5    0.15917199
2376 1     1     6    0.02174757

I would appreciate any help identifying the mistake in my code.

Unai Vicente
  • 367
  • 3
  • 10
  • The `i` in the outer loop doesn't increment until all the `j` and `k` operations are finished. When you run the 100 operations in `j` and `k` for each iteration of `i` it's rewriting over the same row 100 times. – cardinal40 Jan 09 '20 at 20:30
  • Welcome to SO. Please, try to make a complete and reproducible example if you want the people here to help you, see [mcve]. – denis Jan 09 '20 at 20:47
  • That is good insight @cardinal40, any ideas of how should I nest the loops then? I don't see how to add rows automatically for every iteration. – Unai Vicente Jan 09 '20 at 22:12
  • Sorry @denis but I believe the provided code can actually be considered a minimal reproducible example. In fact it is exactly the code I am using. If you could tell me how to be more specific I will be happy to provide with the required additional info. – Unai Vicente Jan 09 '20 at 22:19
  • We don't have the `dyad_data` so it's hard to do much more. – cardinal40 Jan 09 '20 at 22:22
  • I just added a head so you can have a look at the type of data, the problem with `dyad_data` is it has more than 1million observations, and would be difficult to paste here. I meant if given the problem and with the nested loop in mind so I could have the 100 rows at the end, you would do this in a different way @cardinal40. – Unai Vicente Jan 09 '20 at 22:45

1 Answers1

0

You can use bind_rows to append rows to the bottom of a data frame, or rbind with a matrix:

library(dplyr)

df <- 
  tibble::tribble(
  ~Elec1, ~Elec2, ~Dyad,  ~response,
      1,      1,     1, 0.09312585,
      1,      1,     2, 0.09561456,
      1,      1,     3, 0.03530233,
      1,      1,     4, 0.08787908,
      1,      1,     5, 0.15917199,
      1,      1,     6, 0.02174757,
      1,      2,     1, 0.2,
      1,      2,     2, 0.3,
      1,      2,     3, 0.23,
      1,      2,     4, 0.43,
      1,      2,     5, 0.44,
      1,      2,     6, 0.55
  )

summary_df <- 
  tribble(~Elec1, ~Elec2, ~estimate, ~pvalue)

distinct_pairs <- 
  df %>% 
  select(Elec1, Elec2) %>% 
  distinct()

for (i in 1:nrow(distinct_pairs)) {
  model_coefs <- 
    df %>% 
    inner_join(distinct_pairs[i, ], by = c("Elec1", "Elec2")) %>% 
    glm(data = ., formula = response ~ Dyad, family = Gamma(link = "inverse")) %>% 
    summary() %>% 
    coef()

  summary_df <-
    summary_df %>% 
    bind_rows(
      c(distinct_pairs[i, ], 
        estimate = model_coefs[2, 3], 
        pvalue = model_coefs[2, 4])
    )
}

I'm sure there are cleaner ways to solve the problem but this should give you some ideas.

cardinal40
  • 1,245
  • 1
  • 9
  • 11
  • You were right, even though I had some issues at the beginning, this gave me good ideas and I could figure out the best configuration to what I was seeking. Thanks very much @cardinal40. – Unai Vicente Jan 10 '20 at 15:51