मूल्यों के क्रम को बदले बिना किसी कारक का पुन: स्तर


124

मेरे पास कुछ संख्यात्मक चर और कुछ श्रेणीगत चर के साथ डेटा फ़्रेम है factor। उन कारकों के लिए स्तरों का क्रम वैसा नहीं है जैसा मैं चाहता हूं कि वे हों।

numbers <- 1:4
letters <- factor(c("a", "b", "c", "d"))
df <- data.frame(numbers, letters)
df
#   numbers letters
# 1       1       a
# 2       2       b
# 3       3       c
# 4       4       d

यदि मैं स्तरों के क्रम को बदलता हूं, तो पत्र अब अपनी संबंधित संख्या के साथ नहीं हैं (मेरा डेटा इस बिंदु से कुल बकवास है)।

levels(df$letters) <- c("d", "c", "b", "a")
df
#   numbers letters
# 1       1       d
# 2       2       c
# 3       3       b
# 4       4       a

मैं बस स्तर के क्रम को बदलना चाहता हूं , इसलिए जब साजिश रचते हैं, तो बार वांछित क्रम में दिखाए जाते हैं - जो कि डिफ़ॉल्ट वर्णमाला क्रम से भिन्न हो सकते हैं।


1
क्या कोई मुझे संकेत दे सकता है कि स्तर (...) में असाइनमेंट डेटा फ्रेम में प्रविष्टियों के क्रम को क्यों बदलता है, जैसा कि क्रैगोस प्रश्न में दिखाता है? यह मुझे बहुत अचंभित और अवांछित लगता है। मैंने आज कुछ समय अपने आप से इस मुद्दे पर बहस करने में बिताया। मैं सोच रहा हूं कि इस व्यवहार का एक कारण हो सकता है कि मैं हालांकि नहीं देख सकता हूं, या कम से कम एक उचित स्पष्टीकरण क्यों ऐसा होता है।
एंटोन

जवाबों:


120

के levelsतर्क का उपयोग करें factor:

df <- data.frame(f = 1:4, g = letters[1:4])
df
#   f g
# 1 1 a
# 2 2 b
# 3 3 c
# 4 4 d

levels(df$g)
# [1] "a" "b" "c" "d"

df$g <- factor(df$g, levels = letters[4:1])
# levels(df$g)
# [1] "d" "c" "b" "a"

df
#   f g
# 1 1 a
# 2 2 b
# 3 3 c
# 4 4 d

1
धन्यवाद, यह काम किया। कुछ अजीब कारणों से अब ggplot ने किंवदंती में क्रम को सही ढंग से बदल दिया, लेकिन साजिश में नहीं। अजीब।
क्रैगोस

7
ggplot2 को मुझे दोनों (स्तरों को देखें) के क्रम और डेटा फ्रेम के मूल्यों के क्रम को बदलने की आवश्यकता थी। df <- df [nrow (df): 1,] # रिवर्स
क्रैगोस

@ क्रेंगोस, मुझे लगता है कि ggplot स्तरों के वर्णमाला क्रम का उपयोग करता है, और कभी-कभी कस्टम कारक स्तरों की उपेक्षा करता है। कृपया पुष्टि करें, और संस्करण संख्या शामिल करें।
एसएमसीआई

22

कुछ और, सिर्फ रिकॉर्ड के लिए

## reorder is a base function
df$letters <- reorder(df$letters, new.order=letters[4:1])

library(gdata)
df$letters <- reorder.factor(df$letters, letters[4:1])

आपको उपयोगी Relevel और Comb_factor भी मिल सकते हैं ।


2
आपका पहला जवाब मेरे लिए काम नहीं करता है। लेकिन यह काम करता है:reorder(df$letters, seq(4,1))
एलेक्स Holcombe

1
मेरे पास एक बहुत ही अजीब स्थिति है जहां areorder on एक डेटासेट पर काम करता है, दूसरे पर नहीं। अन्य डेटासेट पर, यह एक त्रुटि "टैपली (X = X, INDEX = x, FUN = FUN, ...) में त्रुटि देता है: तर्क" X "गायब है, कोई डिफ़ॉल्ट नहीं है"। निश्चित नहीं है कि इस समस्या का हल क्या है। मुझे डेटासेट के बीच कोई प्रासंगिक अंतर नहीं मिल रहा है।
कोडरग्यूयेज़

10

चूँकि यह प्रश्न अंतिम सक्रिय था इसलिए हैडली ने forcatsकारकों में हेरफेर करने के लिए अपना नया पैकेज जारी किया और मुझे यह अपमानजनक रूप से उपयोगी लगा। ओपी के डेटा फ्रेम से उदाहरण:

levels(df$letters)
# [1] "a" "b" "c" "d"

स्तरों को उलटने के लिए:

library(forcats)
fct_rev(df$letters) %>% levels
# [1] "d" "c" "b" "a"

अधिक स्तर जोड़ने के लिए:

fct_expand(df$letters, "e") %>% levels
# [1] "a" "b" "c" "d" "e"

और कई और उपयोगी fct_xxx()कार्य।


क्या यह अभी भी उपलब्ध है?
जोशुआ रोसेनबर्ग

1
आप इस प्रकार का कोड लिखना चाहते हैं: df %>% mutate(letters = fct_rev(letters))
जाजुर्रो 15

9

तो आप क्या चाहते हैं, आर लेक्सिकॉन में, किसी दिए गए कारक चर के लिए केवल लेबल को बदलना है (यानी, डेटा के साथ-साथ कारक स्तरों को अपरिवर्तित छोड़ दें )।

df$letters = factor(df$letters, labels=c("d", "c", "b", "a"))

यह देखते हुए कि आप केवल डेटापॉइंट-टू-लेबल मैपिंग को बदलना चाहते हैं, न कि डेटा या फैक्टर स्कीमा (कैसे डेटा पॉइंट्स को अलग-अलग डब्बे या फैक्टर वैल्यू में बायन किया जाता है), यह जानने में मदद कर सकता है कि मैपिंग मूल रूप से कैसे सेट की जाती है जब शुरू में बनाते हैं। कारण।

नियम सरल हैं:

  • लेबल को इंडेक्स वैल्यू द्वारा स्तरों पर मैप किया जाता है (यानी, स्तरों का मान [2] लेबल, लेबल [2] दिया जाता है);
  • कारक स्तर स्पष्ट रूप से उन्हें स्तर तर्क के माध्यम से पारित करके निर्धारित किया जा सकता है; या
  • यदि स्तर तर्क के लिए कोई मूल्य नहीं दिया जाता है, तो डिफ़ॉल्ट मान का उपयोग किया जाता है, जो डेटा वेक्टर ( डेटा समस्या के लिए ) में पारित होने पर अद्वितीय कॉलिंग है ;
  • लेबल को तर्क के माध्यम से स्पष्ट रूप से सेट किया जा सकता है; या
  • यदि लेबल तर्क के लिए कोई मूल्य नहीं दिया जाता है, तो डिफ़ॉल्ट मान का उपयोग किया जाता है जो कि केवल स्तर वेक्टर है

1
मुझे नहीं पता कि यह स्वीकार किए गए उत्तर के रूप में मतदान क्यों नहीं है। यह बहुत अधिक जानकारीपूर्ण है।
रामबेटिनो

12
यदि आप इस दृष्टिकोण का उपयोग करते हैं, तो आपका डेटा गलत है।
नज़ीर

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

7

आर में कारकों से निपटना काफी अजीब काम है, मुझे मानना ​​होगा ... कारक स्तरों को पुन: व्यवस्थित करते समय, आप अंतर्निहित संख्यात्मक मानों को पुन: व्यवस्थित नहीं कर रहे हैं। यहाँ थोड़ा प्रदर्शन है:

> numbers = 1:4
> letters = factor(letters[1:4])
> dtf <- data.frame(numbers, letters)
> dtf
  numbers letters
1       1       a
2       2       b
3       3       c
4       4       d
> sapply(dtf, class)
  numbers   letters 
"integer"  "factor" 

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

# return underlying numerical values
1> with(dtf, as.numeric(letters))
[1] 1 2 3 4
# change levels
1> levels(dtf$letters) <- letters[4:1]
1> dtf
  numbers letters
1       1       d
2       2       c
3       3       b
4       4       a
# return numerical values once again
1> with(dtf, as.numeric(letters))
[1] 1 2 3 4

जैसा कि आप देख सकते हैं ... स्तरों को बदलते हुए, आप केवल स्तर बदलते हैं (कौन बताएगा, एह?), संख्यात्मक मान नहीं! लेकिन, जब आप factor@ जोंथन चांग के सुझाव के अनुसार फ़ंक्शन का उपयोग करते हैं, तो कुछ अलग होता है: आप स्वयं संख्यात्मक मान बदलते हैं।

आपको एक बार फिर से त्रुटि हो रही है, क्योंकि आप ऐसा करते हैं levelsऔर फिर इसे पुनः प्रकाशित करने का प्रयास करते हैं factor। यह मत करो !!! करो नहीं का उपयोग levelsया आप गंदगी बातें करेंगे (जब तक आप जानते हैं कि वास्तव में आप क्या कर रहे हैं)।

एक lil 'सुझाव: अपनी वस्तुओं को R के ऑब्जेक्ट्स के रूप में एक समान नाम के साथ नामकरण से बचें ( dfएफ वितरण के लिए घनत्व फ़ंक्शन है, lettersलोअरकेस वर्णमाला पत्र देता है)। इस विशेष मामले में, आपका कोड दोषपूर्ण नहीं होगा, लेकिन कभी-कभी यह हो सकता है ... लेकिन यह भ्रम पैदा कर सकता है, और हम ऐसा नहीं चाहते हैं, क्या हम? =)

इसके बजाय, इस तरह से कुछ का उपयोग करें (मैं शुरुआत से एक बार फिर से जाऊंगा):

> dtf <- data.frame(f = 1:4, g = factor(letters[1:4]))
> dtf
  f g
1 1 a
2 2 b
3 3 c
4 4 d
> with(dtf, as.numeric(g))
[1] 1 2 3 4
> dtf$g <- factor(dtf$g, levels = letters[4:1])
> dtf
  f g
1 1 a
2 2 b
3 3 c
4 4 d
> with(dtf, as.numeric(g))
[1] 4 3 2 1

ध्यान दें कि आप इसके data.frameसाथ dfऔर lettersइसके बजाय नाम भी रख सकते हैं g, और परिणाम ठीक होगा। दरअसल, यह कोड आपके द्वारा पोस्ट किए गए के समान है, केवल नाम बदले गए हैं। यह भाग factor(dtf$letter, levels = letters[4:1])त्रुटि नहीं देगा, लेकिन यह भ्रमित हो सकता है!

?factorमैनुअल को अच्छी तरह से पढ़ें ! बीच क्या अंतर है factor(g, levels = letters[4:1])और factor(g, labels = letters[4:1])? समान में क्या है levels(g) <- letters[4:1]और g <- factor(g, labels = letters[4:1])?

आप ggplot सिंटैक्स लगा सकते हैं, इसलिए हम इस पर आपकी अधिक मदद कर सकते हैं!

चीयर्स !!!

संपादित करें:

ggplot2वास्तव में दोनों स्तरों और मूल्यों को बदलने की आवश्यकता है? हम्म ... मैं इसे बाहर एक खुदाई करेंगे ...


3

मैं एक और मामला जोड़ना चाहता हूं जहां स्तर कुछ विशेष वर्णों के साथ संख्याओं को ले जाने वाले तार हो सकते हैं: उदाहरण के नीचे

df <- data.frame(x = c("15-25", "0-4", "5-10", "11-14", "100+"))

का डिफ़ॉल्ट स्तर xहै:

df$x
# [1] 15-25 0-4   5-10  11-14 100+ 
# Levels: 0-4 100+ 11-14 15-25 5-10

यदि हम संख्यात्मक स्तर के अनुसार कारक स्तरों को फिर से व्यवस्थित करना चाहते हैं, तो स्पष्ट रूप से स्तरों को लिखे बिना, हम क्या कर सकते हैं

library(gtools)
df$x <- factor(df$x, levels = mixedsort(df$x))

df$x
# [1] 15-25 0-4   5-10  11-14 100+ 
# Levels: 0-4 5-10 11-14 15-25 100+
as.numeric(df$x)
# [1] 4 1 2 3 5

मुझे उम्मीद है कि इसे भविष्य के पाठकों के लिए उपयोगी जानकारी माना जा सकता है।


0

यहां दिए गए डेटाफ्रेम के कारकों को फिर से व्यवस्थित करने का मेरा कार्य है:

reorderFactors <- function(df, column = "my_column_name", 
                           desired_level_order = c("fac1", "fac2", "fac3")) {

  x = df[[column]]
  lvls_src = levels(x) 

  idxs_target <- vector(mode="numeric", length=0)
  for (target in desired_level_order) {
    idxs_target <- c(idxs_target, which(lvls_src == target))
  }

  x_new <- factor(x,levels(x)[idxs_target])

  df[[column]] <- x_new

  return (df)
}

उपयोग: reorderFactors(df, "my_col", desired_level_order = c("how","I","want"))

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.