R подсчет строк кадров данных в списке: цикл for ведет себя иначе, чем применение?

Итак, я столкнулся с очень странной проблемой при написании удобной функции для подсчета количества строк в каждом кадре данных в списке кадров данных. Я думаю, что должно быть какое-то базовое поведение, которое мне не хватает, например, индексирование списков не работает так, как я думаю, или что-то принуждается к неправильному типу переменной или что-то в этом роде. Может ли кто-нибудь помочь брату?

Воспроизводимый пример:

myvec <- c(1,2,3,4,5)
df1 <- as.data.frame(rbind(myvec, myvec))
df2 <- as.data.frame(rbind(myvec, myvec, myvec))
dflist <- list(df1, df2)
nrow(dflist[[1]])
# output as expected: [1] 2
nrow(dflist[[2]])
# output as expected: [1] 3

# convenience function 

countrows <- function(pglist) {
  dfsizes <- rep(NA, length(pglist))
  for (i in length(pglist)) {
    dfsizes[i] <- nrow(pglist[[i]])
    return(dfsizes)
  }  
}

newvector <- countrows(dflist)
newvector

# output totally not as expected: [1] NA  3

Я должен пропустить что-то очевидное здесь.

Да, я знаю, что это можно легко сделать с помощью lapply(dflist, nrow) --- и это действительно дает правильный результат. Но ясно, что я не знаю, как правильно перебирать элементы списка, и это проблема, совершенно не связанная с тем, что есть более простой способ сделать то, что я пытаюсь достичь...

Редактировать: добрый комментатор указал, что у меня есть оператор return внутри цикла for, упс. Однако исправление этого по-прежнему дает тот же плохой результат:

countrows2 <- function(pglist) {
  dfsizes <- rep(NA, length(pglist))
  for (i in length(pglist)) {
    dfsizes[i] <- nrow(pglist[[i]])
  }  
  return(dfsizes)
}

doom <- countrows2(dflist)
doom
# still bad output: [1] NA  3

второе редактирование: я плохо избегаю глупых синтаксических ошибок, таких как забывание начать цикл с 1. Двойное возгласы. См. комментарии Нила Фульца, который не так плохо избегает глупых синтаксических ошибок, как я.


person Paul Gowder    schedule 22.05.2015    source источник
comment
Ваше возвращение слишком рано, оно выходит до завершения цикла.   -  person Neal Fultz    schedule 22.05.2015
comment
Я идиот. упс. Спасибо.   -  person Paul Gowder    schedule 22.05.2015
comment
Однако исправленная версия с оператором return вне цикла for по-прежнему выдает такой же плохой результат.   -  person Paul Gowder    schedule 22.05.2015
comment
Попробуйте 1:length(pglist) в цикле for.   -  person Neal Fultz    schedule 22.05.2015
comment
ох. Да. это тоже. столько синтаксических ошибок, все синтаксические ошибки! Это исправило это. Спасибо.   -  person Paul Gowder    schedule 22.05.2015
comment
Когда я запускаю ваш пример и набираю df1, он выдает ошибку: повторяющиеся имена строк.   -  person Frank    schedule 22.05.2015


Ответы (1)


У вашего кода есть проблема, он должен быть 1: длина (pglist), а не просто длина (pglist) в части for(). Вы зациклились на i только по длине (pglist). Также необходимо вывести выражение возврата из цикла.

countrows <- function(pglist) {
  dfsizes <- rep(NA, length(pglist))
  for (i in 1:length(pglist)) {
    dfsizes[i] <- nrow(pglist[[i]])
  }  
  return(dfsizes)
}

newvector <- countrows(dflist)
newvector

Теперь это должно работать так, как ожидалось. Ваше здоровье

Редактировать: мне еще не разрешено комментировать

person user3239929    schedule 22.05.2015