मैं डेटाफ़्रेम में समान नाम वाले स्तंभों की एक सूची (या फ़िल्टर) लेना चाहता हूँ, प्रत्येक पंक्ति के लिए उन स्तंभों के मान का मूल्यांकन करना चाहता हूँ, और फिर परिणाम के साथ एक नया स्तंभ बनाना चाहता हूँ।

अभी मैं case_when का उपयोग कर रहा हूं लेकिन मुझे कुछ वाइल्डकार्ड या परिभाषित कॉलम की सूची प्रदान करने के तरीके के बारे में पता नहीं है।

मैं कॉलम की एक सूची लेना चाहता हूं, या एक फ़िल्टर बनाना चाहता हूं क्योंकि मैं डेटाफ्रेम में कई कॉलम का मूल्यांकन करना चाहता हूं, न कि केवल एक मुट्ठी भर। case_when में स्तंभों की एक लंबी सूची होना कुशल नहीं लगता है जब स्तंभ नाम एक दूसरे के समान होते हैं।

# Dummy data
ignore1 <- c(1, 0, 0)
ignore2 <- c(1, 0, 1)
col1 <- c(0, 1, 0)
col2 <- c(0, 1, 1)
col3 <- c(0, 1, 0)

df <- data.frame(ignore1, ignore2, col1, col2, col3)
df %>% 
  mutate(evaluation = case_when(
    col1 == 0| col1 == 0 | col1 == 0  ~ "Failed",
    TRUE ~ "Passed"
    )
  )

यह अपेक्षित परिणाम है:

  ignore1 ignore2 col1 col2 col3 evaluation
1       1       1    0    0    0     Failed
2       0       0    1    1    1     Passed
3       0       1    0    1    0     Failed

जहां पंक्ति 2 गुजरती है क्योंकि col1, col2, col3 सभी का मान 1 है।

1
Daren Eiri 24 अप्रैल 2020, 05:10

2 जवाब

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

इसे कुशल बनाने के लिए हम केवल rowSums का उपयोग कर सकते हैं

i1 <- startsWith(names(df), 'col')
c( "Failed",  "Passed")[(rowSums(df[i1] == 1) == 3) + 1]
#[1] "Failed" "Passed" "Failed"

या कोई अन्य base R कुशल विकल्प है Reduce

c("Failed", "Passed")[Reduce(`&`, df[i1]) +1]
#[1] "Failed" "Passed" "Failed"

नोट: दोनों base R समाधान कॉम्पैक्ट हैं और बहुत कुशल हैं


या & के साथ

library(dplyr)
df %>% 
     mutate(evaluation =  c('Failed', 'Passed')[1 + (col1 & col2 & col3)])
#  ignore1 ignore2 col1 col2 col3 evaluation
#1       1       1    0    0    0     Failed
#2       0       0    1    1    1     Passed
#3       0       1    0    1    0     Failed

या हमारे पास rowSums dplyr के भीतर हो सकता है

df %>%
   mutate(evaluation = c("Failed", "Passed")[(rowSums(.[i1] == 1) == 3) + 1])

नोट: दोनों समाधान बहुत कुशल हैं और ऐसे किसी भी पैकेज का उपयोग नहीं करते हैं जिनकी वास्तव में आवश्यकता नहीं है

या अगर हमें कुछ पैकेज चाहिए, तो magrittr के साथ purrr का उपयोग करें

library(magrittr)
library(purrr)
df %>% 
   mutate(evaluation = select(., starts_with('col')) %>% 
                          reduce(`&`) %>%
                          add(1) %>%
                          c("Failed", "Passed")[.])
#  ignore1 ignore2 col1 col2 col3 evaluation
#1       1       1    0    0    0     Failed
#2       0       0    1    1    1     Passed
#3       0       1    0    1    0     Failed

नोट: यहां भी, हम पंक्तियों पर लूप नहीं कर रहे हैं, इसलिए यह कुशल होना चाहिए

1
akrun 24 अप्रैल 2020, 21:01
क्या आप अपनी प्रतिक्रिया को संशोधित कर सकते हैं ताकि विशिष्ट कॉलम नाम या सूचकांकों को संदर्भित नहीं किया जा रहा है? col* की तरह?
 – 
Daren Eiri
24 अप्रैल 2020, 19:34
धन्यवाद, मैंने इसे startsWith (i1) में बदल दिया है। क्या आप कृपया जांच सकते हैं कि क्या यह आपके लिए काम करता है
 – 
akrun
24 अप्रैल 2020, 21:01

जैसा कि आप एक पंक्ति-वार ऑपरेशन करना चाहते हैं, हम pmap वेरिएंट का उपयोग कर सकते हैं

library(dplyr)
library(purrr)

df %>% mutate(result =c("Passed","Failed")[pmap_lgl(select(., starts_with('col')),
                       ~any(c(...) == 0)) + 1])

#  ignore1 ignore2 col1 col2 col3 result
#1       1       1    0    0    0 Failed
#2       0       0    1    1    1 Passed
#3       0       1    0    1    0 Failed

आधार R में, हम apply पंक्ति-वार उपयोग कर सकते हैं:

cols <- startsWith(names(df), 'col')
df$Result <- c("Passed", "Failed")[apply(df[cols] == 0, 1, any) + 1]
0
Ronak Shah 24 अप्रैल 2020, 05:21