जानकारी के नुकसान के बिना एक कारक को पूर्णांक \ संख्यात्मक में कैसे परिवर्तित करें?


598

जब मैं एक कारक को संख्यात्मक या पूर्णांक में परिवर्तित करता हूं, तो मुझे अंतर्निहित स्तर कोड मिलते हैं, न कि संख्याओं के रूप में मान।

f <- factor(sample(runif(5), 20, replace = TRUE))
##  [1] 0.0248644019011408 0.0248644019011408 0.179684827337041 
##  [4] 0.0284090070053935 0.363644931698218  0.363644931698218 
##  [7] 0.179684827337041  0.249704354675487  0.249704354675487 
## [10] 0.0248644019011408 0.249704354675487  0.0284090070053935
## [13] 0.179684827337041  0.0248644019011408 0.179684827337041 
## [16] 0.363644931698218  0.249704354675487  0.363644931698218 
## [19] 0.179684827337041  0.0284090070053935
## 5 Levels: 0.0248644019011408 0.0284090070053935 ... 0.363644931698218

as.numeric(f)
##  [1] 1 1 3 2 5 5 3 4 4 1 4 2 3 1 3 5 4 5 3 2

as.integer(f)
##  [1] 1 1 3 2 5 5 3 4 4 1 4 2 3 1 3 5 4 5 3 2

मुझे pasteवास्तविक मूल्य प्राप्त करने के लिए सहारा लेना होगा :

as.numeric(paste(f))
##  [1] 0.02486440 0.02486440 0.17968483 0.02840901 0.36364493 0.36364493
##  [7] 0.17968483 0.24970435 0.24970435 0.02486440 0.24970435 0.02840901
## [13] 0.17968483 0.02486440 0.17968483 0.36364493 0.24970435 0.36364493
## [19] 0.17968483 0.02840901

क्या कारक को संख्यात्मक में बदलने का एक बेहतर तरीका है?


6
एक कारक का स्तर वैसे भी चरित्र डेटा प्रकार के रूप में संग्रहीत किया जाता है ( attributes(f)), इसलिए मुझे नहीं लगता कि इसमें कुछ भी गलत है as.numeric(paste(f))। शायद यह सोचना बेहतर होगा कि क्यों (विशिष्ट संदर्भ में) आपको पहली जगह में एक कारक मिल रहा है, और इसे रोकने की कोशिश करें। उदाहरण के लिए, सही तरीके से सेट किया गया decतर्क read.tableहै?
CJB

यदि आप एक डेटाफ्रेम का उपयोग करते हैं तो आप हबलर से कन्वर्ट का उपयोग कर सकते हैं। df %>% convert(num(column))। या यदि आपके पास एक फैक्टर वेक्टर है तो आप उपयोग कर सकते हैंas_reliable_num(factor_vector)
davsjob

जवाबों:


711

का चेतावनी अनुभाग देखें ?factor:

विशेष रूप से, as.numericएक कारक के लिए लागू अर्थहीन है, और अंतर्निहित जबरदस्ती से हो सकता है। एक कारक fको उसके मूल संख्यात्मक मानों में बदलने के लिए, as.numeric(levels(f))[f]की सिफारिश की जाती है और तुलना में थोड़ा अधिक कुशल होता है as.numeric(as.character(f))

R पर अक्सर पूछे जाने वाले प्रश्न समान सलाह देते हैं


से as.numeric(levels(f))[f]अधिक प्रभावशाली क्यों है as.numeric(as.character(f))?

as.numeric(as.character(f))प्रभावी रूप से है as.numeric(levels(f)[f]), इसलिए आप length(x)मानों के बजाय संख्यात्मक पर मूल्यों में रूपांतरण कर रहे हैं nlevels(x)। कुछ स्तरों के साथ लंबे वैक्टर के लिए गति का अंतर सबसे स्पष्ट होगा। यदि मान अधिकतर विशिष्ट हैं, तो गति में बहुत अंतर नहीं होगा। हालाँकि आप रूपांतरण करते हैं, इस ऑपरेशन में आपके कोड में अड़चन होने की संभावना नहीं है, इसलिए इसके बारे में बहुत चिंता न करें।


कुछ समय

library(microbenchmark)
microbenchmark(
  as.numeric(levels(f))[f],
  as.numeric(levels(f)[f]),
  as.numeric(as.character(f)),
  paste0(x),
  paste(x),
  times = 1e5
)
## Unit: microseconds
##                         expr   min    lq      mean median     uq      max neval
##     as.numeric(levels(f))[f] 3.982 5.120  6.088624  5.405  5.974 1981.418 1e+05
##     as.numeric(levels(f)[f]) 5.973 7.111  8.352032  7.396  8.250 4256.380 1e+05
##  as.numeric(as.character(f)) 6.827 8.249  9.628264  8.534  9.671 1983.694 1e+05
##                    paste0(x) 7.964 9.387 11.026351  9.956 10.810 2911.257 1e+05
##                     paste(x) 7.965 9.387 11.127308  9.956 11.093 2419.458 1e+05

4
समय के लिए यह उत्तर देखें: stackoverflow.com/questions/6979625/…
Ari B. Friedman

3
आपके समाधान के लिए बहुत धन्यवाद। क्या मैं पूछ सकता हूं कि as.numeric (स्तर (f)) [f] अधिक सटीक और तेज क्यों है? धन्यवाद।
सैम

7
@Sam as.character (f) को फंक्शन खोजने के लिए एक "आदिम लुकअप" की आवश्यकता होती है।
जोनाथन

12
जब as.numeric (लेवल (f)) [f] या as.numeric (as.character (f)) लागू होता है, तो मेरे पास एक चेतावनी है संदेश: चेतावनी संदेश: जबरदस्ती द्वारा शुरू किया गया NA। क्या आप जानते हैं कि समस्या कहाँ हो सकती है? धन्यवाद !
मईया

@maycca क्या आपने इस मुद्दे पर काबू पा लिया है?
user08041991

91

कारकों को परिवर्तित करने के लिए R (अनकम्फर्ड) सुविधा कार्यों की एक संख्या है:

  • as.character.factor
  • as.data.frame.factor
  • as.Date.factor
  • as.list.factor
  • as.vector.factor
  • ...

लेकिन गुस्से में, कारक को संभालने के लिए कुछ भी नहीं है -> संख्यात्मक रूपांतरण। जोशुआ उलरिच के उत्तर के विस्तार के रूप में, मैं आपके स्वयं के मुहावरेदार कार्य की परिभाषा के साथ इस चूक को दूर करने का सुझाव दूंगा:

as.numeric.factor <- function(x) {as.numeric(levels(x))[x]}

आप अपनी स्क्रिप्ट की शुरुआत में स्टोर कर सकते हैं, या अपनी .Rprofileफ़ाइल में भी बेहतर कर सकते हैं।


14
फ़ैक्टर-टू-पूर्णांक (या संख्यात्मक) रूपांतरण को संभालने के लिए कुछ भी नहीं है क्योंकि यह उम्मीद है कि as.integer(factor)अंतर्निहित पूर्णांक कोड (जैसा कि उदाहरण अनुभाग में दिखाया गया है ?factor) देता है। इस फ़ंक्शन को अपने वैश्विक परिवेश में परिभाषित करना शायद ठीक है, लेकिन यदि आप वास्तव में इसे S3 विधि के रूप में पंजीकृत करते हैं, तो आपको समस्या हो सकती है।
जोशुआ उलरिक 12

1
यह एक अच्छी बात है और मैं सहमत हूं: कारक का एक पूर्ण पुनर्निर्धारण-> संख्यात्मक रूपांतरण से बहुत सी चीजों को गड़बड़ करने की संभावना है। मुझे लगने बोझिल लेखन factor->numericरूपांतरण एक बहुत एहसास है कि यह अनुसंधान की एक कमी वास्तव में से पहले: कुछ सुविधा समारोह चाहिए उपलब्ध हो ... कॉलिंग यह as.numeric.factorमेरे लिए समझ में आता है, लेकिन YMMV।
जीली

4
यदि आप पाते हैं अपने आप को कर रहा है कि एक बहुत है, तो आप कुछ नदी के ऊपर यह सब एक साथ से बचने के लिए क्या करना चाहिए।
जोशुआ उलरिच

2
as.numeric.factor रिटर्न NA?
जे.ओ.

@jO: उन मामलों में जहां आपने किसी चीज का इस्तेमाल किया v=NA;as.numeric.factor(v)या v='something';as.numeric.factor(v)फिर ऐसा किया जाना चाहिए, नहीं तो आपके पास एक अजीब सी चीज है।
Jealie

33

unfactorपैकेज वारहैंडल से फ़ंक्शन का उपयोग करने का सबसे आसान तरीका होगा

unfactor(your_factor_variable)

यह उदाहरण एक त्वरित शुरुआत हो सकती है:

x <- rep(c("a", "b", "c"), 20)
y <- rep(c(1, 1, 0), 20)

class(x)  # -> "character"
class(y)  # -> "numeric"

x <- factor(x)
y <- factor(y)

class(x)  # -> "factor"
class(y)  # -> "factor"

library(varhandle)
x <- unfactor(x)
y <- unfactor(y)

class(x)  # -> "character"
class(y)  # -> "numeric"

unfactorचरित्र डेटा प्रकार के समारोह धर्मान्तरित पहले और उसके बाद धर्मान्तरित सांख्यिक को वापस। unfactorकंसोल पर टाइप करें और आप इसे फ़ंक्शन के बीच में देख सकते हैं। इसलिए यह वास्तव में बेहतर समाधान नहीं देता है जो पूछने वाले के पास पहले से था।
CJB

यह कहते हुए कि, कारक का स्तर वैसे भी वर्ण प्रकार का होता है, इसलिए इस दृष्टिकोण से कुछ भी नहीं खोता है।
CJB

unfactorसमारोह चीजें हैं जो सांख्यिक को नहीं बदला जा सकता का ख्याल रखता है। उदाहरणों की जाँच करेंhelp("unfactor")
मेहद महमूदियन

2
@ सेलरैक मैंने उल्लेख किया है कि यह फ़ंक्शन वर्धमान पैकेज में उपलब्ध है , जिसका अर्थ है कि आपको पैकेज को लोड करना चाहिए ( library("varhandle")) पहले (जैसा कि मैंने अपने उत्तर की पहली पंक्ति में उल्लेख किया है !!)
मेह्रद महमूदियन

1
@ हल्का निर्भरता जोड़ने से आमतौर पर नुकसान नहीं होता है और निश्चित रूप से यदि आप सबसे कुशल तरीके की तलाश कर रहे हैं, तो कोड को लिखने से आपका स्वयं का प्रदर्शन तेजी से हो सकता है। लेकिन जैसा कि आप अपनी टिप्पणी में भी देख सकते हैं कि यह तुच्छ नहीं है क्योंकि आपने भी ( as.numeric()और as.character()एक गलत क्रम में;) अपने कोड चंक्स को कारक के स्तर सूचकांक को चरित्र मैट्रिक्स में बदलना है, इसलिए आपके पास क्या होगा एक वर्ण वेक्टर है जिसमें कुछ संख्याएं होती हैं जिन्हें एक बार आपके कारक के कुछ निश्चित स्तर पर सौंपा गया है। उस पैकेज में फ़ंक्शंस इन भ्रमों को रोकने के लिए हैं
मेहरड़ महमूदियन

23

नोट: यह विशेष उत्तर संख्यात्मक-मूल्यवान कारकों को संख्यात्मक में परिवर्तित करने के लिए नहीं है , यह श्रेणीगत कारकों को उनकी संबंधित संख्याओं में परिवर्तित करने के लिए है।


इस पोस्ट में हर उत्तर मेरे लिए परिणाम उत्पन्न करने में विफल रहा, NA उत्पन्न हो रहे थे।

y2<-factor(c("A","B","C","D","A")); 
as.numeric(levels(y2))[y2] 
[1] NA NA NA NA NA Warning message: NAs introduced by coercion

मेरे लिए क्या काम किया है -

as.integer(y2)
# [1] 1 2 3 4 1

क्या आप सुनिश्चित हैं कि आपके पास एक कारक था? इस उदाहरण को देखें। y<-factor(c("5","15","20","2")); unclass(y) %>% as.numericयह 4,1,3,2 देता है, न कि 5,15,20,2। यह गलत जानकारी की तरह लगता है।
MrFlick

ठीक है, यह वही है जो मैं आज करने की कोशिश कर रहा था: - y2 <-factor (c ("A", "B", "C", "D", "A")); as.numeric (स्तर (y2)) [y2] [1] NA NA NA NA NA चेतावनी संदेश: जबरदस्ती द्वारा प्रस्तुत NAs जबकि अवर्गीकृत (y2)%>% as.numeric ने मुझे वे परिणाम दिए जिनकी मुझे आवश्यकता थी।
Indi

4
ठीक है, अच्छी तरह से यह सवाल नहीं है जो ऊपर पूछा गया था। इस प्रश्न में कारक स्तर सभी "संख्यात्मक" हैं। आपके मामले में, as.numeric(y)बस ठीक काम किया जाना चाहिए, के लिए कोई ज़रूरत नहीं है unclass()। लेकिन फिर, यह सवाल यह नहीं था। यह उत्तर यहां उचित नहीं है।
MrFlick

3
खैर, मैं वास्तव में आशा करता हूं कि यह किसी ऐसे व्यक्ति की मदद करे, जो मेरी तरह जल्दी में था और सिर्फ शीर्षक पढ़ा!
Indi

1
यदि आपके पास पूर्णांकों को कारकों के रूप में दर्शाने वाले अक्षर हैं, तो यह वही होगा जो मैं सुझाऊँगा। यह केवल वही है जिसने मेरे लिए काम किया है।
लक्ष्य

9

यह केवल उस स्थिति में संभव है जब कारक लेबल मूल मूल्यों से मेल खाते हैं। मैं इसे एक उदाहरण से समझाऊंगा।

मान लें कि डेटा वेक्टर है x:

x <- c(20, 10, 30, 20, 10, 40, 10, 40)

अब मैं चार लेबल वाला एक कारक बनाऊंगा:

f <- factor(x, levels = c(10, 20, 30, 40), labels = c("A", "B", "C", "D"))

1) xटाइप डबल के fसाथ है, टाइप पूर्णांक के साथ है। यह जानकारी का पहला अपरिहार्य नुकसान है। कारक हमेशा पूर्णांक के रूप में संग्रहीत होते हैं।

> typeof(x)
[1] "double"
> typeof(f)
[1] "integer"

2) केवल fउपलब्ध होने वाले मूल मूल्यों (10, 20, 30, 40) पर वापस लौटना संभव नहीं है । हम देख सकते हैं कि fकेवल पूर्णांक मान 1, 2, 3, 4 और दो विशेषताएँ हैं - लेबल की सूची ("ए", "बी", "सी", "डी") और वर्ग विशेषता "कारक"। और कुछ नहीं।

> str(f)
 Factor w/ 4 levels "A","B","C","D": 2 1 3 2 1 4 1 4
> attributes(f)
$levels
[1] "A" "B" "C" "D"

$class
[1] "factor"

मूल मूल्यों पर वापस लौटने के लिए हमें कारक बनाने में उपयोग किए गए स्तरों के मूल्यों को जानना होगा। इस मामले में c(10, 20, 30, 40)। यदि हम मूल स्तरों (सही क्रम में) को जानते हैं, तो हम मूल मूल्यों पर वापस लौट सकते हैं।

> orig_levels <- c(10, 20, 30, 40)
> x1 <- orig_levels[f]
> all.equal(x, x1)
[1] TRUE

और यह केवल उस स्थिति में काम करेगा जब मूल डेटा में सभी संभावित मूल्यों के लिए लेबल परिभाषित किए गए हों।

इसलिए यदि आपको मूल मूल्यों की आवश्यकता होगी, तो आपको उन्हें रखना होगा। अन्यथा एक उच्च संभावना है कि केवल एक कारक से उन्हें वापस प्राप्त करना संभव नहीं होगा।


2

hablar::convertयदि आपके पास डेटा फ्रेम है तो आप इसका उपयोग कर सकते हैं । वाक्य रचना आसान है:

नमूना df

library(hablar)
library(dplyr)

df <- dplyr::tibble(a = as.factor(c("7", "3")),
                    b = as.factor(c("1.5", "6.3")))

समाधान

df %>% 
  convert(num(a, b))

आपको देता है:

# A tibble: 2 x 2
      a     b
  <dbl> <dbl>
1    7.  1.50
2    3.  6.30

या यदि आप चाहते हैं कि एक कॉलम पूर्णांक और एक संख्यात्मक हो:

df %>% 
  convert(int(a),
          num(b))

का परिणाम:

# A tibble: 2 x 2
      a     b
  <int> <dbl>
1     7  1.50
2     3  6.30

0

समाधान के रूप में दिखता है। Numeric (स्तर (f)) [f] अब R 4.0 के साथ काम नहीं करता है।

दूसरा तरीका:

factor2number <- function(x){
    data.frame(levels(x), 1:length(levels(x)), row.names = 1)[x, 1]
}

factor2number(yourFactor)

-1

मेरे द्वारा पढ़े जाने वाले कई उत्तरों से, कारकों की संख्या के अनुसार चर की संख्या का विस्तार करने का एकमात्र तरीका था। यदि आपके पास स्तरों "कुत्ते" और "बिल्ली" के साथ एक चर "पालतू" है, तो आप pet_dog और pet_cat के साथ समाप्त होंगे।

मेरे मामले में मैं एक ही संख्या में चर के साथ रहना चाहता था, बस कारक चर को संख्यात्मक एक में अनुवाद करके, एक तरह से जो कई स्तरों के साथ कई चर पर लागू हो सकता है, ताकि बिल्ली = 1 और कुत्ते = 0 उदाहरण के लिए।

कृपया नीचे दिया गया संगत समाधान खोजें:

crime <- data.frame(city = c("SF", "SF", "NYC"),
                    year = c(1990, 2000, 1990),
                    crime = 1:3)

indx <- sapply(crime, is.factor)

crime[indx] <- lapply(crime[indx], function(x){ 
  listOri <- unique(x)
  listMod <- seq_along(listOri)
  res <- factor(x, levels=listOri)
  res <- as.numeric(res)
  return(res)
}
)

-2

खेल के बाद, अकस्मात, मैंने पाया कि trimws()यह परिवर्तित factor(3:5)हो सकता है c("3","4","5")। तब आप कॉल कर सकते हैं as.numeric()। अर्थात्:

as.numeric(trimws(x_factor_var))

3
क्या कोई कारण है जिसे आप स्वीकार किए गए उत्तर में वर्णित के रूप में उपयोग trimwsकरने की सिफारिश as.characterकरेंगे? यह मुझे ऐसा लगता है जब तक कि आपके पास वास्तव में व्हाट्सएप नहीं था जिसे आपको हटाने की आवश्यकता थी, trimwsबस उसी परिणाम को वापस करने के लिए अनावश्यक नियमित अभिव्यक्ति कार्य का एक गुच्छा करने जा रहा है।
MrFlick

as.numeric (स्तर (f)) [f] शुरुआती लोगों के लिए याद रखने के लिए थोड़ा भ्रमित और कठिन हो सकता है। ट्रिम कोई नुकसान नहीं करता है।
जेरी टी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.