R: перечислить переменную $ i вместо i in for (i в 1:10) - PullRequest
0 голосов
/ 01 мая 2019

Я хочу заменить i в for(i in 1:10) { x*i } на переменную в списке, такую ​​как counter$i

У меня есть несколько циклов for в моем коде, и некоторые из них должны иметь разные переменные подсчета, потому что у меня есть цикл в цикле, что приводит к созданию группы переменных.

Вместо того, чтобы искать другой способ выполнения циклов, такой как версия apply, я решил просто «спрятать» все переменные счетчика в списке, содержащем каждую переменную счетчика, такую ​​как: counter$i для первой переменной и counter$j как второй и т. Д.

Однако для циклов, похоже, не принимают $ или [[]] в переменных счетчика. Есть ли способ, которым я могу достичь этого?

tldr: Я хочу заменить for(i in 1:10) на for(counter$i in 1:10) или эквивалентный

1 Ответ

1 голос
/ 01 мая 2019

Это возможно. Я все еще сомневаюсь в целесообразности этого. (на самом деле не делайте этого , см. ниже). Мне потребуется много времени, чтобы убедить меня в том, что управление такими циклами всегда является "лучшим" решением.

документация для for описывает цикл for с использованием for(var in seq) expr.

var - это «Синтаксическое имя переменной». counter$i не является синтаксическим именем, вы можете заключить его в кавычки, чтобы сделать его синтаксическим.

counter <- list(i = 1)
for (`counter$i` in 1:10){
  print(counter$i)
  counter$i <- counter$i + 1
}

Очевидным недостатком является то, что вам нужно вручную увеличить counter$i (или любые другие счетчики).

Альтернатива

Можно ли установить фрейм данных со всеми условиями, с которыми вы столкнетесь в цикле? Через какую-то комбинацию expand.grid или split?

Обычно, когда я сталкиваюсь с ситуацией, которая может привести к вложенным циклам, я найду способ разделить мои данные так, чтобы каждый список представлял собой элемент, с которым нужно действовать независимо. Тогда мне нужно работать только с одним счетчиком в цикле.

ДОПОЛНЕНИЯ

Что касается дальнейшего созерцания, я думаю, что должен признать, что это на самом деле не "работает". Это работает только в том смысле, что он запутывает итератор вне цикла и позволяет пользователю управлять своим собственным внутренним итератором.

Обратите внимание, что при печати counter$i внутри цикла, но без увеличения вручную, оно никогда не изменяется. Но после того, как мы покидаем цикл, если я получаю объект get("counter$i"), я получаю 10, последнее значение внутреннего итератора цикла.

counter <- list(i = 1)
for (`counter$i` in 1:10){
  # always prints 1
  print(counter$i)
}



`counter$i`
> 10 
get("counter$i")
> 10

По сути, здесь я навязал цикл for, пожертвовав всеми преимуществами управления циклом for. Это подвержено ошибкам и трудно отладить. Хуже того, R уже имеет контроль над тем, чтобы делать именно такие вещи. Это называется repeat.

Я думаю, repeat будет правильным способом приблизиться к тому, что здесь необходимо. Как в

counter <- list(i = 1)
repeat {
  print(counter$i)
  counter$i <- counter$i + 1
  if (counter$i == 10) break;
}

counter$i
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...