आर में कारक: एक झुंझलाहट से अधिक?


95

R में मूल डेटा प्रकारों में से एक कारक है। मेरे अनुभव में कारक मूल रूप से एक दर्द हैं और मैं कभी भी उनका उपयोग नहीं करता। मैं हमेशा किरदारों में बदलता हूं। मुझे अजीब सा लग रहा है जैसे मुझे कुछ याद आ रहा है।

क्या फ़ंक्शन के कुछ महत्वपूर्ण उदाहरण हैं जो कारकों को समूह चर के रूप में उपयोग करते हैं जहां कारक डेटा प्रकार आवश्यक हो जाता है? क्या विशिष्ट परिस्थितियां हैं जब मुझे कारकों का उपयोग करना चाहिए ?


7
मैं शुरुआत करने वाले आर उपयोगकर्ताओं के लिए यह टिप्पणी जोड़ रहा हूं, जो इस प्रश्न को खोजने की संभावना रखते हैं। मैंने हाल ही में एक ब्लॉग पोस्ट लिखी है जो नीचे दिए गए उत्तरों से बहुत सारी जानकारी को निर्देशात्मक ट्यूटोरियल में संकलित करता है कि आर। Gormanalysis.com/?p=115
बेन

मुझे हमेशा लगता था कि कारकों को पात्रों की तुलना में अधिक कुशलता से संग्रहीत किया गया था - जैसे कि प्रत्येक प्रविष्टि स्तर का एक संकेतक था। लेकिन इसे लिखने के लिए परीक्षण करने पर, मुझे पता चला कि यह सच नहीं है!
isomorphismes

2
@isomorphismes अच्छी तरह से, कि इस्तेमाल किया , सच होना आर के पहले दिनों में, लेकिन वह बदल गया है। इस ब्लॉग पोस्ट को देखें: Simplystatistics.org/2015/07/24/…
MichaelChirico

4
5+ साल बाद यह "स्ट्रिंग्सएफ़एक्टर्स: एन अनऑथराइज्ड बायोग्राफी" लिखा गया: Simplystatistics.org/2015/07/24/…
JD Long

जवाबों:


49

आपको कारकों का उपयोग करना चाहिए। हाँ, वे एक दर्द हो सकते हैं, लेकिन मेरा सिद्धांत यह है कि 90% क्यों वे एक दर्द है क्योंकि में है , read.tableऔर read.csv, stringsAsFactors = TRUEडिफ़ॉल्ट रूप से तर्क (और अधिकांश उपयोगकर्ता इस सूक्ष्मता को याद करते हैं)। मैं कहता हूं कि वे उपयोगी हैं क्योंकि lme4 जैसे मॉडल फिटिंग पैकेज कारकों का उपयोग करते हैं और कारकों को अलग-अलग फिट मॉडल का आदेश देते हैं और उपयोग करने के लिए विरोधाभासों के प्रकार का निर्धारण करते हैं। और रेखांकन पैकेज भी उन्हें समूह द्वारा उपयोग करते हैं। ggplotऔर अधिकांश मॉडल फिटिंग कारकों के लिए वैक्टर चरित्र वैक्टर कार्य करते हैं, इसलिए परिणाम समान है। हालाँकि, आप अपने कोड में चेतावनी देते हैं:

lm(Petal.Length ~ -1 + Species, data=iris)

# Call:
# lm(formula = Petal.Length ~ -1 + Species, data = iris)

# Coefficients:
#     Speciessetosa  Speciesversicolor   Speciesvirginica  
#             1.462              4.260              5.552  

iris.alt <- iris
iris.alt$Species <- as.character(iris.alt$Species)
lm(Petal.Length ~ -1 + Species, data=iris.alt)

# Call:
# lm(formula = Petal.Length ~ -1 + Species, data = iris.alt)

# Coefficients:
#     Speciessetosa  Speciesversicolor   Speciesvirginica  
#             1.462              4.260              5.552  

चेतावनी संदेश model.matrix.default(mt, mf, contrasts):

चर में Speciesपरिवर्तितfactor

एक मुश्किल बात पूरे drop=TRUEबिट है। वैक्टर में यह उन कारकों के स्तर को हटाने के लिए अच्छी तरह से काम करता है जो डेटा में नहीं हैं। उदाहरण के लिए:

s <- iris$Species
s[s == 'setosa', drop=TRUE]
#  [1] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [11] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [21] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [31] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [41] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# Levels: setosa
s[s == 'setosa', drop=FALSE]
#  [1] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [11] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [21] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [31] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [41] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# Levels: setosa versicolor virginica

हालाँकि , के साथ data.frame, का व्यवहार [.data.frame()अलग है: इस ईमेल को देखें या ?"[.data.frame"। का उपयोग drop=TRUEपर data.frameरों काम नहीं करता है के रूप में आप कल्पना चाहते हैं:

x <- subset(iris, Species == 'setosa', drop=TRUE)  # susbetting with [ behaves the same way
x$Species
#  [1] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [11] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [21] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [31] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [41] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# Levels: setosa versicolor virginica

सौभाग्य से आप droplevels()एक कारक के लिए अप्रयुक्त कारक स्तरों को छोड़ने के लिए या data.frame(2. R के बाद से 2.12) में प्रत्येक कारक के लिए आसानी से कारकों को छोड़ सकते हैं :

x <- subset(iris, Species == 'setosa')
levels(x$Species)
# [1] "setosa"     "versicolor" "virginica" 
x <- droplevels(x)
levels(x$Species)
# [1] "setosa"

यह है कि आप उन स्तरों को कैसे रखें जिन्हें आपने ggplotकिंवदंतियों में जाने से चुना है ।

आंतरिक रूप से, factorएस एक विशेषता स्तर चरित्र वेक्टर (देखें attributes(iris$Species)और class(attributes(iris$Species)$levels)) के साथ पूर्णांक हैं , जो साफ है। यदि आपको एक स्तर नाम बदलना था (और आप वर्ण स्ट्रिंग का उपयोग कर रहे थे), तो यह बहुत कम कुशल संचालन होगा। और मैं स्तर के नाम को बहुत बदल देता हूं, खासकर ggplotकिंवदंतियों के लिए। यदि आप चरित्र वैक्टर के साथ नकली कारक हैं, तो जोखिम है कि आप सिर्फ एक तत्व को बदल देंगे, और गलती से एक नया स्तर बना सकते हैं।


1
stringsAsFactorsकोई फ़ंक्शन नहीं है।
IRTFM

30

आदेशित कारक भयानक हैं, अगर मुझे संतरे से प्यार है और सेब से नफरत है, लेकिन बुरा मत मानना, मुझे ऐसा कहने के लिए कुछ अजीब सूचकांक का प्रबंधन करने की आवश्यकता नहीं है:

d <- data.frame(x = rnorm(20), f = sample(c("apples", "oranges", "grapes"), 20, replace = TRUE, prob = c(0.5, 0.25, 0.25)))
d$f <- ordered(d$f, c("apples", "grapes", "oranges"))
d[d$f >= "grapes", ]

यह एक साफ अनुप्रयोग है। ऐसा कभी नहीं सोचा था।
JD लॉन्ग

क्या किया d$f <- ordered(d$f, c("apples", "grapes", "oranges"))? मैंने अनुमान लगाया होगा कि इसने डेटा फ्रेम में इनका आदेश दिया था, लेकिन जब मैंने उस लाइन को चलाया और डेटा फ्रेम को प्रिंट किया, तो कुछ भी नहीं बदला। क्या यह सिर्फ एक आंतरिक आदेश थोपता है भले ही मुद्रित आदेश नहीं बदलता है?
अदीम

... हाँ, मुझे लगता है कि मैंने जो लिखा वह एक सही वाक्य की तरह था। अगर मुझे आपकी बात समझ में आ रही है, तो आप हमें दिखा रहे हैं कि आप कारकों पर एक आदेश दे सकते हैं, जो कि आप कुछ नहीं कर सकते हैं।
अदीम

4
आदेश दिया () किसी भी मूल्यों से एक मनमाना आदेश बनाता है - जिस क्रम में आप कहते हैं कि वे आदेश दिए गए हैं। यह दुर्भाग्यपूर्ण है कि मैंने lexicographically सॉर्ट किए गए मानों का उपयोग किया, यह एक संयोग है। उदाहरण के लिए मैं इसका उपयोग डेटा के लिए करता हूं जहां "Z" खराब है, "3" अच्छा है लेकिन लेबल संख्यात्मक या वर्णानुक्रमिक नहीं हैं - इसलिए मैं ऑर्डर करता हूं (डेटा, c ("Z", "B", "A", ") 0 "," 1 "," 2 "," 3 ")) और इसलिए मैं सिर्फ डेटा>" ए "कर सकता हूं और यह सुखद दिन हैं।
मध्याह्न

19

A factorअन्य भाषाओं में एक प्रगणित प्रकार के लिए सबसे अधिक अनुरूप है। इसका उचित उपयोग एक चर के लिए है जो केवल निर्धारित मानों में से एक पर ले सकता है। इन मामलों में, डेटा के किसी विशेष सेट में हर संभव अनुमत मूल्य मौजूद नहीं हो सकता है और "खाली" स्तर सटीक रूप से यह दर्शाता है।

कुछ उदाहरणों पर गौर कीजिए। कुछ आंकड़ों के लिए जो पूरे संयुक्त राज्य में एकत्र किए गए थे, राज्य को एक कारक के रूप में दर्ज किया जाना चाहिए। इस मामले में, यह तथ्य कि कोई भी मामला किसी विशेष राज्य से एकत्र नहीं किया गया है, प्रासंगिक है। उस स्थिति से डेटा हो सकता था, लेकिन वहां हुआ (जो भी कारण, जो कि ब्याज का एक कारण हो सकता है) नहीं होना। यदि गृहनगर एकत्र किया गया था, तो यह एक कारक नहीं होगा। संभावित गृहनगर का एक पूर्व-निर्धारित सेट नहीं है। यदि राष्ट्रीय स्तर के बजाय तीन शहरों से डेटा एकत्र किया गया था, तो शहर एक कारक होगा: तीन विकल्प हैं जो शुरुआत में दिए गए थे और यदि उन तीन शहरों में से एक में कोई प्रासंगिक मामले / डेटा नहीं पाए गए, तो यह प्रासंगिक है।

factorS के अन्य पहलू , जैसे कि स्ट्रिंग्स के एक सेट को एक मनमाना क्रम देने का तरीका प्रदान करना, s की उपयोगी माध्यमिक विशेषताएँ हैं factor, लेकिन उनके अस्तित्व का कारण नहीं हैं।


3
+1। ब्रायन, मुझे लगता है कि आपने डेटा में मौजूद स्तर को कैप्चर करने के साथ सिर पर कील ठोक दी।
रिकार्डो सपोर्टा

13

कारक शानदार हैं जब कोई सांख्यिकीय विश्लेषण कर रहा है और वास्तव में डेटा की खोज कर रहा है। हालांकि, इससे पहले कि जब कोई पढ़ रहा हो, सफाई, समस्या निवारण, विलय और आम तौर पर डेटा में हेरफेर कर रहा हो, तो कारक कुल दर्द होते हैं। हाल ही में, पिछले कुछ वर्षों में कारकों को बेहतर ढंग से संभालने के लिए बहुत सारे कार्यों में सुधार हुआ है। उदाहरण के लिए, rbind उनके साथ अच्छी तरह से खेलता है। मुझे अभी भी यह एक कुल उपद्रव लगता है कि एक उप-समारोह के बाद खाली स्तरों पर छोड़ दिया गया है।

#drop a whole bunch of unused levels from a whole bunch of columns that are factors using gdata
require(gdata)
drop.levels(dataframe)

मुझे पता है कि एक कारक के स्तरों को फिर से बनाना और लेबल को फिर से जोड़ना सरल है और स्तरों को फिर से व्यवस्थित करने के लिए अद्भुत तरीके भी हैं। मेरा मस्तिष्क अभी उन्हें याद नहीं कर सकता है और मुझे इसका हर बार उपयोग करने से पहले इसे त्यागना होगा। रिकोडिंग की तुलना में यह बहुत आसान होना चाहिए।

R के स्ट्रिंग फ़ंक्शंस उपयोग करने में काफी आसान और तार्किक हैं। इसलिए जब मैं हेरफेर करता हूं तो आम तौर पर कारकों पर चरित्र पसंद करता हूं।


1
क्या आपके पास आँकड़ों के विश्लेषण के उदाहरण हैं जो कारकों का उपयोग करते हैं?
JD लॉन्ग

3
अब एक बेस-आर फ़ंक्शन है droplevels()। और यह डिफ़ॉल्ट रूप से कारकों को फिर से आदेश नहीं देता है।
बेन बोल्कर

6

क्या एक घिनौना शीर्षक!

मेरा मानना ​​है कि कई अनुमान कार्य आपको डमी चर को आसानी से परिभाषित करने के लिए कारकों का उपयोग करने की अनुमति देते हैं ... लेकिन मैं उनके लिए उपयोग नहीं करता हूं।

मैं उनका उपयोग तब करता हूं जब मेरे पास कुछ अद्वितीय टिप्पणियों के साथ बहुत बड़े वर्ण वैक्टर होते हैं। यह स्मृति की खपत में कटौती कर सकता है, खासकर अगर चरित्र वेक्टर में तार लंबे-ईश हैं।

पीएस - मैं शीर्षक के बारे में मजाक कर रहा हूं। मैंने आपका ट्वीट देखा। ;-)


1
तो तुम सच में बस उन्हें भंडारण स्थान के संरक्षण के लिए उपयोग करें। यह समझ आता है।
जद लॉन्ग

13
कम से कम; लेकिन कुछ आर संस्करण पहले चरित्र भंडारण आंतरिक रूप से हैशेड होने के लिए फिर से लिखा गया था इसलिए इस ऐतिहासिक तर्क का हिस्सा अब शून्य है। अभी भी कारक समूह और मॉडलिंग के लिए बहुत उपयोगी हैं ।
डिर्क एडल्डबुलेटेल

1
इसके अनुसार ?factorयह R-2.6.0 था और यह कहता है, "पूर्णांक मान 4 बाइट्स में संग्रहीत होते हैं जबकि वर्ण स्ट्रिंग के प्रत्येक संदर्भ को 4 या 8 बाइट्स के सूचक की आवश्यकता होती है।" यदि आप चरित्र स्ट्रिंग 8 बाइट्स की जरूरत है कारक के लिए अंतरिक्ष को बचाने बचा सकता है?
जोशुआ उलरिच

2
एन <- 1000; एक <- नमूना (सी ("ए", "बी", "सी"), एन, प्रतिस्थापित = ट्रू); प्रिंट (ऑब्जेक्ट.साइज़ (ए), यूनिट्स = "Kb"); प्रिंट (ऑब्जेक्ट.साइज़ (कारक) ()), इकाइयाँ = "Kb"); 8 Kb 4.5 Kb तो यह अभी भी कुछ जगह बचाने के लिए लगता है।
एडुआर्डो लियोनी

2
@ ईदुर्डो I को 4Kb बनाम 4.2Kb मिला। के लिए N=100000मैं 391.5 Kb बनाम 391.8 Kb मिला। इसलिए कारक थोड़ी अधिक स्मृति लेता है।
मारेक

1

कारक एक उत्कृष्ट "अद्वितीय-केस" बैजिंग इंजन हैं। मैंने इसे कई बार बुरी तरह से बनाया है, और कभी-कभी झुर्रियों के एक जोड़े के बावजूद, वे बेहद शक्तिशाली हैं।

library(dplyr)
d <- tibble(x = sample(letters[1:10], 20, replace = TRUE))

## normalize this table into an indexed value across two tables
id <- tibble(x_u = sort(unique(d$x))) %>% mutate(x_i = row_number())
di <- tibble(x_i = as.integer(factor(d$x)))


## reconstruct d$x when needed
d2 <- inner_join(di, id) %>% transmute(x = x_u)
identical(d, d2)
## [1] TRUE

यदि इस कार्य को करने का एक बेहतर तरीका है, तो मैं इसे देखना पसंद करूंगा, मुझे factorचर्चा की यह क्षमता दिखाई नहीं दे रही है।


-2

tapply (और एग्रीगेट ) कारकों पर भरोसा करते हैं। इन कार्यों का सूचना-से-प्रयास अनुपात बहुत अधिक है।

उदाहरण के लिए, कोड की एक पंक्ति में ( नीचे टैप करने के लिए कॉल ) आप कट और रंग द्वारा हीरे की औसत कीमत प्राप्त कर सकते हैं:

> data(diamonds, package="ggplot2")

> head(dm)

   Carat     Cut    Clarity Price Color
1  0.23     Ideal     SI2   326     E
2  0.21   Premium     SI1   326     E
3  0.23      Good     VS1   327     E


> tx = with(diamonds, tapply(X=Price, INDEX=list(Cut=Cut, Color=Color), FUN=mean))

> a = sort(1:diamonds(tx)[2], decreasing=T)  # reverse columns for readability

> tx[,a]

         Color
Cut         J    I    H    G    F    E    D
Fair      4976 4685 5136 4239 3827 3682 4291
Good      4574 5079 4276 4123 3496 3424 3405
Very Good 5104 5256 4535 3873 3779 3215 3470
Premium   6295 5946 5217 4501 4325 3539 3631
Ideal     4918 4452 3889 3721 3375 2598 2629

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