आर: को रोकने में एक पाश जब एक शर्त पूरी कर रहा है

0

सवाल

मैं काम कर रहा हूँ के साथ आर प्रोग्रामिंग भाषा है । मैं निम्नलिखित बनाया लूप उत्पन्न करता है कि 1000 यादृच्छिक संख्या - और फिर इस प्रक्रिया को दोहराता है 10 गुना:

results <- list()

for (i in 1:10){

a = rnorm(1000,10,1)
b = rnorm(1000,10,1)


d_i = data.frame(a,b)
d_i$index = 1:nrow(d_i)
d_i$iteration = as.factor(i)

 results[[i]] <- d_i

}



results_df <- do.call(rbind.data.frame, results)

प्रश्न: मैं इस परिवर्तन करना चाहते पाश है कि इस तरह के बजाय केवल पैदा 1000 यादृच्छिक संख्या, यह रहता है यादृच्छिक संख्या पैदा करने के लिए जब तक एक निश्चित शर्त पूरी कर रहा है, उदाहरण के लिए: रखने के लिए यादृच्छिक संख्या पैदा करने के लिए जब तक d_i$a > 10 और d_i$b > 10.

का उपयोग कर एक "जबकि()" बयान में, मैं ऐसा करने की कोशिश की:

results <- list()

for (i in 1:10){

 while (d_i$a > 10 & d_i$b >10) {

a = rnorm(1000,10,1)
b = rnorm(1000,10,1)


d_i = data.frame(a,b)
d_i$index = 1:nrow(d_i)
d_i$iteration = as.factor(i)

 results[[i]] <- d_i

}

}


results_df <- do.call(rbind.data.frame, results)

समस्या: हालांकि, इस रिटर्न निम्न चेतावनी (10 बार):

Warning messages:
1: In while (d_i$a > 10 & d_i$b > 10) { :
  the condition has length > 1 and only the first element will be used

और उत्पादन में एक खाली टेबल:

> results_df

data frame with 0 columns and 0 rows

कर सकते हैं किसी को मदद के लिए कृपया मुझे इस समस्या को ठीक?

धन्यवाद!

data-manipulation loops r while-loop
2021-11-23 23:09:34
3

सबसे अच्छा जवाब

3

त्रुटि संदेश में मूल पोस्ट कर रहे हैं कि इस तथ्य के कारण d_i$a और d_i$b कर रहे हैं के साथ वैक्टर के 1,000 तत्वों और 10 है एक अदिश. इसलिए, अनुसंधान की तुलना में पहला तत्व d_i$a और पहला तत्व में d_i$b के साथ 10.

को हल करने के लिए त्रुटि संदेश हम की जरूरत की तुलना करने के लिए एक वेक्टर की लंबाई के साथ 1 करने के लिए अदिश 10. इस की आवश्यकता है पुनर्गठन करने के लिए कोड उत्पन्न यादृच्छिक संख्या, एक समय में एक. से विवरण में मूल पोस्ट है, यह स्पष्ट नहीं है कि क्या इस व्यवहार जानबूझकर किया गया था.

मैं इस समस्या को सरल बनाने को नष्ट करने के द्वारा सेट की 10 अनुकरण करने के लिए वर्णन कैसे बनाने के लिए एक डेटा फ्रेम के साथ यादृच्छिक संख्या, जब तक एक पंक्ति है दोनों a और b मूल्यों के साथ तुलना में अधिक से अधिक 10.

सबसे पहले, हम सेट एक बीज बनाने के लिए जवाब प्रतिलिपि प्रस्तुत करने योग्य, और फिर प्रारंभ कुछ वस्तुओं. सेटिंग के द्वारा a और b 0 करने के लिए हम सुनिश्चित करें कि while() पाश निष्पादित करेंगे कम से कम एक बार.

set.seed(950141238) # for reproducibility 
results <- list()
a <- 0 # initialize a to a number < 10
b <- 0 # initialize b to a number < 10 
i <- 1 # set a counter 

होने प्रारंभ a और bमें , while() पाश का मूल्यांकन करने के लिए TRUE दो यादृच्छिक संख्या उत्पन्न करता है, प्रदान करती है एक सूचकांक मूल्य, और लिखते हैं के रूप में उन्हें एक डेटा फ्रेम करने के लिए results सूची. तर्क के लिए while() पाश है कि इंगित करता है यदि या तो a कम से कम या 10 के बराबर या b से कम या बराबर करने के लिए 10, पाश रहता है पुनरावृति. यह बंद हो जाता है जब दोनों a और b से अधिक कर रहे हैं 10.

while(a <= 10 | b <= 10){
     a <- rnorm(1,10,1) # generate 1 random number with mean of 10 and sd of 1
     b <- rnorm(1,10,1) # ditto
     results[[i]] <- data.frame(index = i,a,b)
     i <- i + 1 # increment i
}

पाश बंद हो जाता है को क्रियान्वित करने के बाद नौवें चलना के रूप में हम देख सकते हैं मुद्रण द्वारा जिसके परिणामस्वरूप डेटा फ्रेम के बाद हम गठबंधन के अलग-अलग पंक्तियों के साथ do.call() और rbind().

df <- do.call(rbind,results)
df

...और उत्पादन:

> df
  index         a         b
1     1  8.682442  8.846653
2     2  9.204682  8.501692
3     3  8.886819 10.488972
4     4 11.264142  8.952981
5     5  9.900112 10.918042
6     6  9.185120 10.625667
7     7  9.620793 10.316724
8     8 11.718397  9.256835
9     9 10.034793 11.634023
>

ध्यान दें कि अंतिम पंक्ति में डेटा सीमा के मूल्यों की तुलना में अधिक से अधिक 10 के लिए दोनों a और b.

कई अनुकरण जबकि पाश के

करने के लिए इस प्रक्रिया को दोहराएँ 10 बार के रूप में किया जाता है मूल पोस्ट में, हम लपेट आपरेशन में एक for() पाश, जोड़ने और एक दूसरी सूची, combined_results परिणामों को बचाने के लिए प्रत्येक से चलना.

set.seed(950141238) # for reproducibility 
combined_results <- list()
for(iteration in 1:10){
     results <- list()
     a <- 0 # initialize a to a number < 10
     b <- 0 # initialize b to a number < 10 
     i <- 1 # set a counter 
     while((a < 10) | (b < 10)){
          a <- rnorm(1,10,1) # generate 1 random number with mean of 10 and sd of 1
          b <- rnorm(1,10,1) # ditto
          results[[i]] <- data.frame(iteration,index = i,a,b)
          i <- i + 1 # increment i
     }
     combined_results[[iteration]] <- do.call(rbind,results)
}
df <- do.call(rbind,combined_results)
df[df$iteration < 5,] 

...और उत्पादन के लिए 4 iterations के बाहरी पाश:

> df[df$iteration < 5,]
   iteration index         a         b
1          1     1  8.682442  8.846653
2          1     2  9.204682  8.501692
3          1     3  8.886819 10.488972
4          1     4 11.264142  8.952981
5          1     5  9.900112 10.918042
6          1     6  9.185120 10.625667
7          1     7  9.620793 10.316724
8          1     8 11.718397  9.256835
9          1     9 10.034793 11.634023
10         2     1 11.634331  9.746453
11         2     2  9.195410  7.665265
12         2     3 11.323344  8.279968
13         2     4  9.617224 11.792142
14         2     5  9.360307 11.166162
15         2     6  7.963320 11.325801
16         2     7  8.022093  8.568503
17         2     8 10.440788  9.026129
18         2     9 10.841408 10.033346
19         3     1 11.618665 10.179793
20         4     1 10.975061  9.503309
21         4     2 10.209288 12.409656
> 

फिर हम ध्यान दें कि अंतिम पंक्ति में प्रत्येक यात्रा (9, 18, 19, 21) है, मूल्यों की तुलना में अधिक से अधिक 10 के लिए दोनों a और b.

ध्यान दें कि इस दृष्टिकोण में विफल रहता है का लाभ लेने के लिए vectorized संचालन अनुसंधान में, जिसका अर्थ है कि पैदा करने के बजाय 1,000 यादृच्छिक संख्या के साथ प्रत्येक कॉल करने के लिए rnorm(), कोड के आधार पर एक while() उत्पन्न एक यादृच्छिक संख्या प्रति कॉल करने के लिए rnorm(). के बाद से rnorm() एक संसाधन गहन कार्य, कोड को कम करता है कि बार की संख्या rnorm() कार्यान्वित वांछनीय है.

2021-11-24 20:45:06
2

मुझे आशा है कि इन टिप्पणियों में मदद करने के लिए का पालन करें यह कैसे काम करता है. यह मुख्य रूप से का उपयोग करता है repeat बस है जो एक अनंत लूप. यह किया जा सकता का उपयोग बंद कर दिया break कीवर्ड.

results <- list()


for (i in 1:10){
  
  # do until break
  repeat {
    
    # repeat many random numbers
    a = rnorm(1000,10,1)
    b = rnorm(1000,10,1)
    
    # does any pair meet the requirement
    if (any(a > 10 & b > 10)) {
      
      # put it in a data.frame
      d_i = data.frame(a,b)
      
      # end repeat
      break
    }
  }
  
  # select all rows until the first time the requirement is met
  # it must be met, otherwise the loop would not have ended
  d_i <- d_i[1:which(d_i$a > 10 & d_i$b > 10)[1], ]
  
  # prep other variables
  d_i$index = seq_len(nrow(d_i))
  d_i$iteration = as.factor(i)
  
  results[[i]] <- d_i
  
}
2021-11-24 01:19:52
2

करने के लिए एक पाश से बाहर तोड़ने के (या के लिए), बस पर एक break() के बाद एक if हालत.

out <- vector("integer", 26)
for (i in seq_along(letters)) {
  if(letters[i] == "t") break()
  out[i] <- i+1
}
out
#> [1]  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20  0  0  0  0  0  0  0

होगा एक पाश से बाहर तोड़ने. से ?break: नियंत्रण स्थानांतरित करने के लिए पहली बयान के बाहर-भीतर सबसे पाश ।

हालांकि, अपने प्रश्न से यह पूरी तरह स्पष्ट नहीं है क्यों आप कर रहे हैं की कोशिश कर रहा है - यह इस तरह के प्रवाह को नियंत्रित नहीं किया जा सकता है उपयुक्त समाधान के रूप में, एक vectorized समाधान मौजूद हो सकता है । इसके अलावा, सावधान रहना करने के अनावश्यक चीजों के अंदर एक पाश - यह एक आम कारण के लिए धीमी गति से चल रहा है कोड. यहाँ हम कर सकते हैं कुछ चीजें लेने के लिए-के पाश के लिए, इस तरह के रूप में d_i$iteration और d_i$indexहै , और अभी भी अंत में एक ही परिणाम के साथ. पर एक नजर है तीसरे चक्र है.

2021-11-23 23:46:14

अन्य भाषाओं में

यह पृष्ठ अन्य भाषाओं में है

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................