विशिष्ट आदेश के साथ वेक्टर के अनुसार डेटा फ़्रेम पंक्तियों को ऑर्डर करें


158

क्या यह सुनिश्चित करने का एक आसान तरीका है कि डेटा फ्रेम की पंक्तियों को "लक्ष्य" वेक्टर के अनुसार आदेश दिया जाए, जैसा कि मैंने नीचे दिए उदाहरण में लागू किया था?

df <- data.frame(name = letters[1:4], value = c(rep(TRUE, 2), rep(FALSE, 2)))

df
#   name value
# 1    a  TRUE
# 2    b  TRUE
# 3    c FALSE
# 4    d FALSE

target <- c("b", "c", "a", "d")

यह किसी भी तरह काम करने के लिए थोड़ा "जटिल" प्रतीत होता है:

idx <- sapply(target, function(x) {
    which(df$name == x)
})
df <- df[idx,]
rownames(df) <- NULL

df 
#   name value
# 1    b  TRUE
# 2    c FALSE
# 3    a  TRUE
# 4    d FALSE

जवाबों:


232

कोशिश करें match:

df <- data.frame(name=letters[1:4], value=c(rep(TRUE, 2), rep(FALSE, 2)))
target <- c("b", "c", "a", "d")
df[match(target, df$name),]

  name value
2    b  TRUE
3    c FALSE
1    a  TRUE
4    d FALSE

यह तब तक काम करेगा, जब तक कि आपके targetतत्वों में ठीक वैसा ही तत्व df$nameन हो, और न ही डुप्लिकेट मान हों।

से ?match:

match returns a vector of the positions of (first) matches of its first argument 
in its second.

इसलिए matchउन पंक्ति संख्याओं को खोजता है जो targetतत्वों से मेल खाते हैं, और फिर हम dfउसी क्रम में लौटते हैं ।


महान, यह अधिक पसंद है और वास्तव में मैं क्या देख रहा था! बहुत बहुत धन्यवाद
रैपस्टर

1
एक सवाल, क्या होगा अगर मैं जिस कॉलम को मैच करना चाहूंगा उसमें रिपीट वैल्यू है? पसंद है b,c,a,d,b,c,a,d। मैंने कोशिश की matchलेकिन यह अच्छी तरह से काम नहीं करता है।
यूलोंग

@ यूलोंग: मुझे लगता है कि आपको स्पष्ट रूप से यह सुनिश्चित करना होगा कि डुप्लिकेट को फायरिंग से पहले हटा दिया जाए match()। मन में क्या आता है duplicated(), unique()या कुछ अन्य कस्टम दिनचर्या जो दूसरों को दूर फेंकते समय वांछित तत्वों को "रखता है"। HTH
रैप्टर

@ यह एक अच्छा समाधान है। हालांकि, यह सूचकांकों को भी बदलता है। मैं उन्हें आरोही क्रम (1, 2, 3, 4) में कैसे रख सकता हूं?
हसन इकबाल

2
यकीन नहीं है कि यह सबसे साफ तरीका है, लेकिन केवल "आधार" कार्यों के साथ, यह काम करना चाहिए यदि आपके पास df में डुप्लिकेट है:df <- data.frame(name=letters[c(1:4, 1:4)], value=c(rep(TRUE, 2), rep(FALSE, 2),rep(TRUE, 2), rep(FALSE, 2) )) target <- c("b", "c", "a", "d") df[order(unlist(sapply(df$name, function(x) which(target == x)))),]
एरिका फेरी

21

जब भी मुझे डेटा का मिलान करने की आवश्यकता होती है, ***_join में उपयोग करना पसंद करता dplyrहूं। इसके लिए एक मुमकिन कोशिश

left_join(data.frame(name=target),df,by="name")

ध्यान दें कि इनपुट के लिए ***_jointbls या data.frame की आवश्यकता होती है


हाँ, * _join फ़ंक्शन dplyrवास्तव में अच्छे हैं। अब तक इनका भरपूर उपयोग करते हुए समाप्त करें
रैपरस्टर

इस स्थिति में, डेटा से बचने के लिए टारबल के रूप में टारगेट ऑर्डर घोषित करने की सलाह देते हैं। target <- tibble(name = c("b", "c", "a", "d"))
नेटल

2
और पाइप सिंटैक्स के साथ:df %>% right_join(tibble(name = target), by = "name")
फ्रैंक

18

यह विधि थोड़ी अलग है, इसने मुझे पिछले उत्तर की तुलना में थोड़ा अधिक लचीलापन प्रदान किया है। एक आदेशित कारक में बनाकर, आप इसे अच्छी तरह से arrangeऔर इस तरह से उपयोग कर सकते हैं । मैंने gdataपैकेज से reorder.factor का उपयोग किया ।

df <- data.frame(name=letters[1:4], value=c(rep(TRUE, 2), rep(FALSE, 2)))
target <- c("b", "c", "a", "d")

require(gdata)
df$name <- reorder.factor(df$name, new.order=target)

अगला, इस तथ्य का उपयोग करें कि यह अब आदेश दिया गया है:

require(dplyr)
df %>%
  arrange(name)
    name value
1    b  TRUE
2    c FALSE
3    a  TRUE
4    d FALSE

यदि आप मूल (अल्फाबेटिक) ऑर्डर पर वापस जाना चाहते हैं, as.character()तो इसे मूल स्थिति में वापस लाने के लिए उपयोग करें।


2
क्या किसी को इसके बारे में डेटा संस्करण के बारे में पता है?
रिलस्टीन

2
@Reilstein setDT(df)[ , name := factor(name, levels = target)]। फिर दो data.tableउत्तर यहां देखें
हेनरिक

4

हम इसके आधार पर कारक स्तरों को समायोजित कर सकते हैं targetऔर इसका उपयोग कर सकते हैंarrange

library(dplyr)
df %>% arrange(factor(name, levels = target))

#  name value
#1    b  TRUE
#2    c FALSE
#3    a  TRUE
#4    d FALSE

या orderयह और इसे में उपयोग करेंslice

df %>% slice(order(factor(name, levels = target)))

2
सबसे अच्छा समाधान IMO
स्टीववे

1
मेरे लिए सबसे अच्छा और सरल उपाय।
Matt_B

0

यदि आप किसी भी पुस्तकालयों का उपयोग नहीं करना चाहते हैं और आपके डेटा में reoccurrences हैं, तो आप के whichसाथ भी उपयोग कर सकते हैं sapply

new_order <- sapply(target, function(x,df){which(df$name == x)}, df=df)
df        <- df[new_order,]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.