मुझे नियमित अभिव्यक्तियों के आधार पर चर बनाने में मदद चाहिए।

यह मेरा डेटाफ्रेम है:

df <- data.frame(a=c("blue", "red", "yellow", "yellow", "yellow", "yellow", "red"), b=c("apple", "orange", "peach", "lemon", "pineapple", "tomato", NA))

मूल रूप से, मैं यह करना चाहता हूं, लेकिन एक चरण में:

regx_1 <- as.numeric(grep("^[a-z]{5}$", df$b))
regx_2 <- as.numeric(grep("^[a-z]{6,}$", df$b))
df$fruit_1 <- NA
df$fruit_1[regx_1 + 1] <- as.character(df$b[regx_1])

df$fruit_2 <- NA
df$fruit_2[regx_2 + 1] <- as.character(df$b[regx_2])

यहाँ मेरी कोशिश है:

regex1 <- "^[a-z]{5}$"
regex2 <- "^[a-z]{6,}$"
regex <- c(regex1, regex1)

make_non_matches_NA <- function(vec, pattern){
  df[[newvariable]] <- NA
  df[[newvariable]][as.numeric(grep(pattern, vec)) + 1] <- as.character(vec[as.numeric(grep(pattern, vec))])
  return(newvariable)
}

df[c("fruit1", "fruit2")] <- lapply(regex, make_non_matches_NA, vec = df$b)

संपादित करें: मेरा दृष्टिकोण गलत क्यों है? (कृपया ध्यान दें कि वास्तविक समस्या बड़ी है, इसलिए मुझे एक दृष्टिकोण पर टिके रहना है, जहां एक पैटर्न की पुनरावृत्ति से बचा जाना चाहिए)

किसी भी प्रकार की मदद की बेहद सराहना की जाती है!

1
stefan485 21 नवम्बर 2019, 17:23

2 जवाब

सबसे बढ़िया उत्तर

आपके कार्यक्षेत्र में क्रमांकित आइटम होना एक अच्छा संकेत है कि वे वास्तव में एक सूची से संबंधित हैं, इसलिए वे औपचारिक रूप से जुड़े हुए हैं और हम उनके साथ अधिक आसानी से काम कर सकते हैं। तो चलिए पहले ऐसा करते हैं।

regex <- c("^[a-z]{5}$", "^[a-z]{6,}$")

हमारी मुख्य कार्यक्षमता स्रोत वेक्टर की प्रतिलिपि बनाना है, लेकिन मेल नहीं खाने वाले तत्वों को हटाना है, और NA को उनके स्थान पर छोड़ देना है, इसलिए हम उसके लिए एक फ़ंक्शन बनाएंगे, और हम इसे स्पष्ट रूप से नाम देंगे ताकि हम समझ सकें सहजता से यह क्या कर रहा है (और जैसा कि हमारे सहयोगी SO पर अगले पाठक होंगे;)):

make_non_matches_NA <- function(vec, pattern){
  # logical indices of matches
  matches_lgl <- grepl(pattern, vec)
  # the elements which don't match should be NA
  vec[!matches_lgl] <- NA
  # resulting vector should be returned
  vec
}

आइए पहले पैटर्न के साथ इसका परीक्षण करें

make_non_matches_NA(df$b, regex[[1]])
#> [1] apple <NA>  peach lemon <NA>  <NA> 
#> Levels: apple lemon orange peach pineapple tomato

अब तक सब ठीक है! अब आइए सभी रेगेक्स के साथ इसका परीक्षण करें, हम लूप से बचते हैं जब हम आम तौर पर आर में कर सकते हैं क्योंकि हमारे पास lapply() जैसे स्पष्ट उपकरण हैं। यहां मैं इस फ़ंक्शन को सभी रेगेक्स अभिव्यक्तियों पर लागू करना चाहता हूं:

lapply(regex, make_non_matches_NA, vec = df$b)
#> [[1]]
#> [1] apple <NA>  peach lemon <NA>  <NA> 
#> Levels: apple lemon orange peach pineapple tomato
#> 
#> [[2]]
#> [1] <NA>      orange    <NA>      <NA>      pineapple tomato   
#> Levels: apple lemon orange peach pineapple tomato

बढ़िया, यह काम करता है!

लेकिन मैं इसे अपने डेटा.फ्रेम में चाहता हूं, एक अलग सूची के रूप में नहीं, इसलिए मैं इस परिणाम को सीधे अपने डीएफ में प्रासंगिक नामों को निर्दिष्ट करूंगा

df[c("fruit1", "fruit2")] <- lapply(regex, make_non_matches_NA, vec = df$b)
# then print my updated df
df
#>   a         b fruit1    fruit2
#> 1 1     apple  apple      <NA>
#> 2 2    orange   <NA>    orange
#> 3 3     peach  peach      <NA>
#> 4 4     lemon  lemon      <NA>
#> 5 5 pineapple   <NA> pineapple
#> 6 6    tomato   <NA>    tomato

टाडा!

2
Moody_Mudskipper 21 नवम्बर 2019, 21:12
आपके उत्तर के लिए धन्यवाद मूडी! आपके उत्तर दोनों विशिष्ट समस्या से दृढ़ता से संबंधित हैं, इसलिए यह मेरी गलती है कि मैंने गलत पूछा। मेरे डेटा में, एक चरण अधिक जटिल है, इसलिए मुझे लगता है कि मुझे 2 चरणों की प्रक्रिया के इस जटिल पैटर्न को खोजने की आवश्यकता है और इस पैटर्न का उपयोग इस एकाधिक चरणों के निष्पादन के लिए करें (आवश्यक नहीं कि "लूप के लिए")। तो अधिक सटीक होने के लिए, कमोबेश एक स्पष्टीकरण की आवश्यकता है कि मेरा दृष्टिकोण काम क्यों नहीं करता है।
 – 
stefan485
21 नवम्बर 2019, 20:22
मुझे आशा है कि मेरा नया उत्तर बेहतर काम करेगा। मैंने चरणों का विस्तार करने की कोशिश की, और इससे भी महत्वपूर्ण बात, तर्क। आर पहली बार में निराशाजनक हो सकता है लेकिन इस मुद्दे को छोटे टुकड़ों में काटने में मदद करता है और सुनिश्चित करता है कि आप प्रत्येक चरण को 100% समझते हैं, इससे भविष्य में आपका बहुत समय बच जाएगा।
 – 
Moody_Mudskipper
21 नवम्बर 2019, 21:15
ओह हाँ मैं देखता हूँ! फ़ंक्शन तब काम करने के लिए तेजी से काम करता है लेकिन लूप ओवर अभी भी टूटा हुआ है। यानी df <- create.function(df, "b", "fruit_1", regx_1) अब अलग से काम करता है।
 – 
stefan485
21 नवम्बर 2019, 21:15
क्या मैं आपसे एक बार फिर पूछ सकता हूं कि इसी तरह की समस्या के लिए मेरा अद्यतन प्रयास क्यों काम नहीं करता है? :/
 – 
stefan485
22 नवम्बर 2019, 17:20
1
1) आप सही कह रहे हैं, vec को स्पष्ट रूप से खिलाया जाता है, इसलिए regex को तत्व दर तत्व, अगले तर्क के लिए पारित किया जाता है, जो कि pattern है
 – 
Moody_Mudskipper
22 नवम्बर 2019, 19:09

मुझे नहीं लगता कि यह "एक कदम पर" के रूप में योग्य है, लेकिन आप dplyr पैकेज से mutate आज़मा सकते हैं:

df <- data.frame(a=c(1:6), b=c("apple", "orange", "peach", "lemon", "pineapple", "tomato"), 
                 stringsAsFactors = FALSE)

ध्यान दें कि मैंने stringsAsFactors = FALSE data.frames के अंदर सेट किया है।

dplyr::mutate(df, fruit_1 = if_else(grepl("^[a-z]{5}$", b), b, NA_character_),
       fruit_2 = if_else(grepl("^[a-z]{6}$", b), b, NA_character_))

  a         b fruit_1 fruit_2
1 1     apple   apple    <NA>
2 2    orange    <NA>  orange
3 3     peach   peach    <NA>
4 4     lemon   lemon    <NA>
5 5 pineapple    <NA>    <NA>
6 6    tomato    <NA>  tomato
1
Cettt 21 नवम्बर 2019, 17:47
धन्यवाद केट! आपका उत्तर वास्तव में मेरी मदद करता है, लेकिन मैं इसे अपने कोड में नहीं अपना सकता, क्योंकि यह पर्याप्त लचीला नहीं है और मैं केवल कोड के कुछ हिस्सों को छोटा कर सकता हूं। मुझे अपना प्रश्न अलग तरीके से रखना होगा: मैं कुछ कोड के पैटर्न पर कैसे लूप कर सकता हूं जहां किसी फ़ंक्शन या इसी तरह के परिवर्तनों को संक्षेप में प्रस्तुत किया जाता है।
 – 
stefan485
21 नवम्बर 2019, 20:33