#r
Вопрос:
Предположим, у меня есть список номеров.
x <- c(10,12,5,23,40,27,11,4,7,25,21,7,99,45,2,10)
Я хочу напечатать первые 5 чисел, превышающих 20, используя условие if внутри цикла for, поскольку это простой воспроизводимый пример, и фактический сценарий требует условий if внутри циклов. Есть ли способ получить первые 5 чисел больше 20 без ограничения диапазона? Способ найти все числа, превышающие 20, был бы примерно таким
for(i in 1:length(x)){
if(x[i]>20){
print(x[i])
}
}
Проблему также можно рассматривать как ограничение инструкции print первыми 5 экземплярами.
Кто-нибудь может помочь?
Пожалуйста, обратите внимание, что диапазон цикла for не может быть ограничен для достижения решения.
Требуемым ответом было бы
23,40,27,25,21
Использование для цикла, если условие и инструкция печати/cat/линии записи являются обязательными
Комментарии:
1. Нормально ли выходить из цикла , когда есть 5 попаданий, или в не упрощенном цикле происходит что-то еще, что нужно сделать для остальных.
2. Предпочтительно, чтобы вариант использования успешно прошел весь список значений и вернул первые 5, которые удовлетворяют условию. Он также должен возвращать ИСТИННЫЕ условия, даже если условие не оценивается в 5 ИСТИННЫХ условий. Например, логика должна быть для первых 5, но даже если мы получим всего 2 условия вместо максимум 5, то эти 2 должны быть напечатаны. Что касается вашего вопроса, я предполагаю, что в этом случае повторение всего цикла при выполнении первых 5 условий было бы пустой тратой памяти?
3. Спасибо. Хорошо, но тогда также было бы возможно решение, которое уже ограничивает диапазон
for
цикла.4. Я тоже думал об этом. Не могли бы вы сказать мне, о чем именно вы думаете?
5. Например:
for(i in which(cumsum(x > 20) <= 5)) {...
Ответ №1:
Сработает ли это:
x[x > 20][1:5]
[1] 23 40 27 25 21
Использование для цикла:
v <- vector()
for(i in 1:length(x)){
if(x[i] > 20){
v <- c(v,x[i])
}
if(length(v) == 5){
print(v)
break
}
}
[1] 23 40 27 25 21
Комментарии:
1. Это даст сомнительные результаты, если будет меньше 5 результатов.
2. В данном случае это работает. Но в случае использования требуется использовать инструкцию print внутри условия if внутри для циклов. Я постарался изложить это как можно проще!
3. @Nil_07, добавили
for
цикл, пожалуйста, проверьте, работает ли это4. Я попробую это для своего случая @Karthik S. Между тем ваше решение и решение GKi ниже выглядят похожими и полезными.
5. @Nil_07, это в основном создание пустого вектора и заполнение его в соответствии с нашими условиями.
Ответ №2:
Поскольку оказалось, что ограничение диапазона цикла for разрешено, это можно было бы сделать с помощью cumsum(x > 20) <= 5
:
for(i in seq_len(match(5, cumsum(x > 20), length(x)))) {
if(x[i] > 20) {
print(x[i])
}
}
#[1] 23
#[1] 40
#[1] 27
#[1] 25
#[1] 21
Или добавьте счетчик:
Вариант, который сломается после 5 попаданий (благодаря @sindri-baldur):
n <- 0L
for(i in 1:length(x)){
if(x[i]>20) {
print(x[i])
n <- n 1L
if(n == 5L) break
}
}
Вариант, который сделает полный цикл.
n <- 0L
for(i in 1:length(x)){
if(x[i]>20 amp; n<5) {
n <- n 1L
print(x[i])
}
}
Чтобы получить первые 5, вы можете использовать head
:
head(x[x > 20], 5)
#[1] 23 40 27 25 21
Обратите внимание, что это также будет работать в тех случаях, когда попаданий меньше 5. Затем он вернет количество обращений. Например, попробуйте сделать это с:
x <- c(10,12,5,23,40,27,11,4,7,25,2,7,9,4,2,10)
Комментарии:
1. Я бы добавил вместо
if (n == 5L) break
этого в случаеx
, если это очень долго.2. @sindri_baldur Я не знаю, что еще произойдет в не упрощенном цикле. И в вопросе я могу читать, не ограничивая диапазон . Но, возможно
break
, можно было бы использовать, но это ограничит диапазон.3. @sindri_baldur Спасибо за подсказку. На самом деле оказывается, что ограничение диапазона допустимо. Поэтому я добавляю вариант с вашим предложением.