मैं डेटाफ़्रेम में समान नाम वाले स्तंभों की एक सूची (या फ़िल्टर) लेना चाहता हूँ, प्रत्येक पंक्ति के लिए उन स्तंभों के मान का मूल्यांकन करना चाहता हूँ, और फिर परिणाम के साथ एक नया स्तंभ बनाना चाहता हूँ।
अभी मैं 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
है।
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
नोट: यहां भी, हम पंक्तियों पर लूप नहीं कर रहे हैं, इसलिए यह कुशल होना चाहिए
जैसा कि आप एक पंक्ति-वार ऑपरेशन करना चाहते हैं, हम 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]
col*
की तरह?startsWith
(i1
) में बदल दिया है। क्या आप कृपया जांच सकते हैं कि क्या यह आपके लिए काम करता है