মানের ক্রম পরিবর্তন না করে একটি ফ্যাক্টরের স্তরগুলিকে পুনঃক্রম করুন


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,] # বিপরীত
ক্র্যাঙ্গোস

@ ক্র্যাঙ্গোস, আমি মনে করি জিজিপ্লট স্তরগুলির বর্ণানুক্রমিক ক্রম ব্যবহার করে এবং কখনও কখনও কাস্টম ফ্যাক্টরের স্তরগুলিকে উপেক্ষা করে। দয়া করে নিশ্চিত করুন এবং সংস্করণ নম্বর অন্তর্ভুক্ত করুন।
স্মি

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])

আপনি দরকারী রিলেভেল এবং কম্বাইনে_ ফ্যাক্টরটিও পেতে পারেন ।


2
আপনার প্রথম উত্তর আমার পক্ষে কাজ করে না। তবে এটি কাজ করে:reorder(df$letters, seq(4,1))
অ্যালেক্স হলকম্ব

1
আমার খুব অদ্ভুত পরিস্থিতি আছে যেখানে ´reord´ অন্যের সাথে নয়, একটি ডেটাसेटে কাজ করে on অন্য ডেটাসেটে এটি "ত্যাপি ত্রুটি (এক্স = এক্স, আইএনডিএক্স = এক্স, ফুন = ফুন, ...): ত্রুটিটি" এক্স "অনুপস্থিত, কোনও ডিফল্ট ছাড়াই" ছুড়ে দেয় "dat এই সমস্যার সমাধান কী তা নিশ্চিত নয়। আমি ডেটাসেটের মধ্যে কোনও প্রাসঙ্গিক পার্থক্য খুঁজে পাই না।
কোডারগুই 123

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))
jazzurro

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 বা আপনি জিনিসগুলি জগাখিচুড়ি করবেন (যদি না আপনি জানেন যে ঠিক কী করছেন)।

একটি লিলের পরামর্শ: আপনার অবজেক্টের নাম আর এর অবজেক্ট হিসাবে অভিন্ন নাম দিয়ে এড়িয়ে চলুন ( 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"))

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.