প্রতিটি ফ্যাক্টর স্তরের জন্য 1 টি সূচক ভেরিয়েবলের সংকলনে স্বয়ংক্রিয়ভাবে একটি আর ফ্যাক্টর প্রসারিত করা


108

আমার কাছে একটি আর ডেটা ফ্রেম রয়েছে যাতে আমি একটি ফ্যাক্টরটি "প্রসারিত" করতে পারি যাতে প্রতিটি ফ্যাক্টর স্তরের জন্য একটি নতুন ডেটা ফ্রেমে একটি যুক্ত কলাম থাকে, এতে 1/0 সূচক থাকে। যেমন ধরুন আমার কাছে রয়েছে:

df.original <-data.frame(eggs = c("foo", "foo", "bar", "bar"), ham = c(1,2,3,4))

আমি চাই:

df.desired  <- data.frame(foo = c(1,1,0,0), bar=c(0,0,1,1), ham=c(1,2,3,4))

কারণ নির্দিষ্ট বিশ্লেষণগুলির জন্য যার জন্য আপনার সম্পূর্ণ সংখ্যার ডেটা ফ্রেম থাকা দরকার (যেমন, মূল উপাদান বিশ্লেষণ), আমি ভেবেছিলাম এই বৈশিষ্ট্যটি অন্তর্নির্মিত হতে পারে this এটি করার জন্য কোনও ফাংশন লেখা খুব শক্ত হওয়া উচিত নয়, তবে আমি কিছুটা ধারণা করতে পারি কলামের নাম সম্পর্কিত চ্যালেঞ্জগুলি এবং যদি ইতিমধ্যে কিছু উপস্থিত থাকে তবে আমি এটি ব্যবহার করব।

উত্তর:


131

model.matrixফাংশনটি ব্যবহার করুন :

model.matrix( ~ Species - 1, data=iris )

1
আমি কি যুক্ত করতে পারি যে এই পদ্ধতিটি castআমার জন্য ব্যবহারের চেয়ে অনেক দ্রুত ছিল ।
ম্যাট ওয়েলার

3
@ গ্রেগস্নো আমি ?formulaপাশাপাশি দ্বিতীয় অনুচ্ছেদটিও পর্যালোচনা করেছি ?model.matrix, তবে এটি অস্পষ্ট ছিল (ম্যাট্রিক্স বীজগণিত এবং মডেল গঠনের ক্ষেত্রে আমার জ্ঞানের গভীরতার অভাব হতে পারে)। আরও খনন করার পরে, আমি সংগ্রহ করতে সক্ষম হয়েছি যে -1 কেবল "ইন্টারসেপ্ট" কলামটি অন্তর্ভুক্ত না করার জন্য নির্দিষ্ট করে দিচ্ছে। আপনি যদি -1 ছাড়েন, তবে আউটপুটে 1 টির একটি ইন্টারসেপ্ট কলাম দেখতে পাবেন যার মধ্যে একটি বাইনারি কলাম রয়েছে। অন্যান্য কলামগুলির মান 0 এর যেখানে সারণীদের উপর ভিত্তি করে বাদ দেওয়া কলামটি 1 এর মানগুলি দেখতে সক্ষম। ডকুমেন্টেশন রহস্যজনক বলে মনে হচ্ছে - অন্য কোন ভাল উত্স আছে?
রায়ান চেস

1
@ রায়ানচেস, আর / এস সম্পর্কে অনেকগুলি অনলাইন টিউটোরিয়াল এবং বই রয়েছে (বেশ কয়েকটিতে যা r-project.org ওয়েবপৃষ্ঠায় সংক্ষিপ্ত বিবরণ রয়েছে)। এস এবং আর সম্পর্কে আমার নিজস্ব শিক্ষার পরিবর্তে সারগ্রাহী (এবং দীর্ঘ) হয়েছে, সুতরাং বর্তমান বই / টিউটোরিয়ালগুলি কীভাবে নতুনদের কাছে আবেদন করে তা সম্পর্কে আমি মতামত জানাতে সেরা নই। আমি অবশ্য পরীক্ষার ভক্ত। একটি নতুন আর অধিবেশনে কিছু চেষ্টা করা খুব আলোকিত এবং বিপজ্জনক হতে পারে না (আমার সাথে সবচেয়ে খারাপটি ঘটেছে আর ক্র্যাশ করছে, এবং এটি খুব কমই, যা আর এর উন্নতির দিকে নিয়ে যায়)। স্ট্যাকওভারফ্লো তখন কী হয়েছিল তা বোঝার জন্য একটি ভাল উত্স।
গ্রেগ তুষার

7
এবং আপনি যদি সমস্ত ফ্যাক্টর কলাম রূপান্তর করতে চান তবে আপনি এটি ব্যবহার করতে পারেন:model.matrix(~., data=iris)[,-1]
user890739

1
@ কলিন, সম্পূর্ণ স্বয়ংক্রিয় নয়, তবে আপনি naresidঅনুপস্থিত মানগুলি ব্যবহারের পরে ফিরিয়ে আনতে পারেন na.exclude। একটি দ্রুত উদাহরণ:tmp <- data.frame(x=factor(c('a','b','c',NA,'a'))); tmp2 <- na.exclude(tmp); tmp3 <- model.matrix( ~x-1, tmp2); tmp4 <- naresid(attr(tmp2,'na.action'), tmp3)
গ্রেগ তুষার

17

যদি আপনার ডেটা ফ্রেমটি শুধুমাত্র ফ্যাক্টরগুলি দিয়ে তৈরি হয় (বা আপনি যে সমস্ত ভেরিয়েবলের একটি উপসেটে কাজ করছেন) তবে আপনি প্যাকেজ acm.disjonctifথেকে ফাংশনটি ব্যবহার করতে পারেন ade4:

R> library(ade4)
R> df <-data.frame(eggs = c("foo", "foo", "bar", "bar"), ham = c("red","blue","green","red"))
R> acm.disjonctif(df)
  eggs.bar eggs.foo ham.blue ham.green ham.red
1        0        1        0         0       1
2        0        1        1         0       0
3        1        0        0         1       0
4        1        0        0         0       1

আপনি যে বর্ণনা করছেন ঠিক তেমনটি নয়, তবে এটি কার্যকরও হতে পারে ...


ধন্যবাদ, এটি আমাকে অনেক বেশি সহায়তা করেছে কারণ এটি তখন কম স্মৃতি ব্যবহার করে মডেল.ম্যাট্রিক্স!
সারেহি

ভেরিয়েবলের নামকরণের পদ্ধতিটি আমার পছন্দ; আমি অপছন্দ করি যে, তারা স্টোরেজ-ক্ষুধার্ত সাংখ্যিক যখন তারা যেমন ফিরিয়ে আনা হয় উচিত (এই প্রোগ্রামটিতে) শুধু logicals হও।
dsz

9

reshape2প্যাকেজটি ব্যবহারের একটি দ্রুত উপায় :

require(reshape2)

> dcast(df.original, ham ~ eggs, length)

Using ham as value column: use value_var to override.
  ham bar foo
1   1   0   1
2   2   0   1
3   3   1   0
4   4   1   0

মনে রাখবেন এটি আপনার পছন্দসই কলামের নামগুলি উত্পন্ন করে।


ভাল. তবে হ্যামের সদৃশ যত্ন নিন। বলুন, ডি <- ডেটা.ফ্রেমে (ডিম = সি ("ফু", "বার", "ফু"), হ্যাম = সি (1,2,1)); ডাস্টক্ট (ডি, হাম ~ ডিম, দৈর্ঘ্য) foo = 2 তোলে
কোহস্কে

@ কোহসকে, সত্য, তবে আমি ধরে নিচ্ছিলাম hamযে একটি অনন্য রো আইডি। যদি hamকোনও অনন্য আইডি না হয় তবে অবশ্যই অন্য কোনও অনন্য-আইডি ব্যবহার করতে হবে (বা একটি ডামি তৈরি করতে হবে) এবং সেই জায়গায় ব্যবহার করতে হবে ham। একটি শ্রেণিবদ্ধ লেবেলটিকে বাইনারি সূচকে রূপান্তর করা কেবল অনন্য আইডির জন্য অর্থবোধ করবে।
প্রসাদ চালশানী

6

সম্ভবত ডামি ভেরিয়েবল আপনি যা চান তার অনুরূপ। তারপরে, Model.matrix দরকারী:

> with(df.original, data.frame(model.matrix(~eggs+0), ham))
  eggsbar eggsfoo ham
1       0       1   1
2       0       1   2
3       1       0   3
4       1       0   4

6

প্যাকেজ class.indথেকে দেরী প্রবেশnnet

library(nnet)
 with(df.original, data.frame(class.ind(eggs), ham))
  bar foo ham
1   0   1   1
2   0   1   2
3   1   0   3
4   1   0   4

4

কেবলমাত্র এই পুরানো থ্রেডটি জুড়ে এসেছিল এবং ভেবেছিলাম যে আমি একটি ফাংশন যুক্ত করব যা উপাদানগুলি এবং / অথবা সংখ্যাসূচক ডেটা সমন্বিত ডেটাফ্রেম গ্রহণের জন্য এডি 4 ব্যবহার করে এবং ডামি কোড হিসাবে ফ্যাক্টর সহ একটি ডেটাফ্রেম ফেরত দেয়।

dummy <- function(df) {  

    NUM <- function(dataframe)dataframe[,sapply(dataframe,is.numeric)]
    FAC <- function(dataframe)dataframe[,sapply(dataframe,is.factor)]

    require(ade4)
    if (is.null(ncol(NUM(df)))) {
        DF <- data.frame(NUM(df), acm.disjonctif(FAC(df)))
        names(DF)[1] <- colnames(df)[which(sapply(df, is.numeric))]
    } else {
        DF <- data.frame(NUM(df), acm.disjonctif(FAC(df)))
    }
    return(DF)
} 

চল এটা চেষ্টা করি.

df <-data.frame(eggs = c("foo", "foo", "bar", "bar"), 
            ham = c("red","blue","green","red"), x=rnorm(4))     
dummy(df)

df2 <-data.frame(eggs = c("foo", "foo", "bar", "bar"), 
            ham = c("red","blue","green","red"))  
dummy(df2)

3

এটি করার আরও সুস্পষ্ট উপায় এখানে। আমি ডামি বুলিয়ান ভেরিয়েবলগুলি তৈরি করতে মডেল.ম্যাট্রিক্স ব্যবহার করি এবং তারপরে এটিকে আবার মূল ডেটাফ্রেমে একীভূত করি।

df.original <-data.frame(eggs = c("foo", "foo", "bar", "bar"), ham = c(1,2,3,4))
df.original
#   eggs ham
# 1  foo   1
# 2  foo   2
# 3  bar   3
# 4  bar   4

# Create the dummy boolean variables using the model.matrix() function.
> mm <- model.matrix(~eggs-1, df.original)
> mm
#   eggsbar eggsfoo
# 1       0       1
# 2       0       1
# 3       1       0
# 4       1       0
# attr(,"assign")
# [1] 1 1
# attr(,"contrasts")
# attr(,"contrasts")$eggs
# [1] "contr.treatment"

# Remove the "eggs" prefix from the column names as the OP desired.
colnames(mm) <- gsub("eggs","",colnames(mm))
mm
#   bar foo
# 1   0   1
# 2   0   1
# 3   1   0
# 4   1   0
# attr(,"assign")
# [1] 1 1
# attr(,"contrasts")
# attr(,"contrasts")$eggs
# [1] "contr.treatment"

# Combine the matrix back with the original dataframe.
result <- cbind(df.original, mm)
result
#   eggs ham bar foo
# 1  foo   1   0   1
# 2  foo   2   0   1
# 3  bar   3   1   0
# 4  bar   4   1   0

# At this point, you can select out the columns that you want.

0

আমার 'বিস্ফোরিত' ফ্যাক্টরগুলির দরকার ছিল যা কিছুটা আরও নমনীয় and এটি আপনাকে বিস্ফোরিত মানগুলি চয়ন করতে দেয়, যা acm.disjonctif এ 0 এবং 1 হয়। এটি কেবলমাত্র 'কয়েকটি' স্তরযুক্ত কারণগুলির বিস্ফোরণ ঘটায়। সংখ্যাযুক্ত কলামগুলি সংরক্ষিত আছে।

# Function to explode factors that are considered to be categorical,
# i.e., they do not have too many levels.
# - data: The data.frame in which categorical variables will be exploded.
# - values: The exploded values for the value being unequal and equal to a level.
# - max_factor_level_fraction: Maximum number of levels as a fraction of column length. Set to 1 to explode all factors.
# Inspired by the acm.disjonctif function in the ade4 package.
explode_factors <- function(data, values = c(-0.8, 0.8), max_factor_level_fraction = 0.2) {
  exploders <- colnames(data)[sapply(data, function(col){
      is.factor(col) && nlevels(col) <= max_factor_level_fraction * length(col)
    })]
  if (length(exploders) > 0) {
    exploded <- lapply(exploders, function(exp){
        col <- data[, exp]
        n <- length(col)
        dummies <- matrix(values[1], n, length(levels(col)))
        dummies[(1:n) + n * (unclass(col) - 1)] <- values[2]
        colnames(dummies) <- paste(exp, levels(col), sep = '_')
        dummies
      })
    # Only keep numeric data.
    data <- data[sapply(data, is.numeric)]
    # Add exploded values.
    data <- cbind(data, exploded)
  }
  return(data)
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.