একটি ডেটা ফ্রেমে কীভাবে একটি পুনরায় ক্রম করে?


311

কীভাবে এই ইনপুটটি পরিবর্তন করা হবে (ক্রম সহ: সময়, সময়, আউট, ফাইল):

Time   In    Out  Files
1      2     3    4
2      3     4    5

এই আউটপুট (ক্রম সহ: সময়, আউট, ইন, ফাইল)?

Time   Out   In  Files
1      3     2    4
2      4     3    5

এখানে ডামি আর ডেটা রয়েছে:

table <- data.frame(Time=c(1,2), In=c(2,3), Out=c(3,4), Files=c(4,5))
table
##  Time In Out Files
##1    1  2   3     4
##2    2  3   4     5

4
help(Extract)?'['
জোরিস মাইস

3
@ জোরিসের পরামর্শ ছাড়াও, "আর পরিচিতির সাথে
গাভিন সিম্পসন

3
একটি অতিরিক্ত সমস্যা: সমস্ত উত্তরগুলির জন্য কলামগুলির সম্পূর্ণ তালিকা প্রয়োজন, অন্যথায় সেগুলি সাবসেটিংয়ের ফলস্বরূপ। যদি আমরা কেবলমাত্র কয়েকটি কলামকে প্রথমে আদেশ করার মতো তালিকা তৈরি করতে চাই, তবে অন্য সমস্তগুলি ধরে রাখি তবে কী হবে?
000andy8484

উত্তর:


341

আপনার ডেটাফ্রেমে এর মতো চারটি কলাম রয়েছে df[,c(1,2,3,4)]। নোট করুন প্রথম কমা মানে সমস্ত সারি রাখা, এবং 1,2,3,4 কলামগুলিকে বোঝায়।

উপরের প্রশ্নের মতো অর্ডার পরিবর্তন করতে হবে df2[,c(1,3,2,4)]

আপনি যদি এই ফাইলটিকে সিএসভি হিসাবে আউটপুট করতে চান তবে করুন write.csv(df2, file="somedf.csv")


35
আপনার যখন সীমাবদ্ধ সংখ্যক কলাম রয়েছে তখন এটি ঠিক আছে, তবে আপনার যদি উদাহরণস্বরূপ 50 টি কলাম থাকে তবে সমস্ত কলাম নম্বর বা নাম টাইপ করতে খুব বেশি সময় লাগবে। এর দ্রুত সমাধান কী হবে?
হারমান টুথরট

53
@ ব্যবহারকারী 4050: সেক্ষেত্রে আপনি ":" সিনট্যাক্স, উদাহরণস্বরূপ ডিএফ [, সি (1,3,2,4,5: 50)] ব্যবহার করতে পারেন।
dalloliogm

1
শুরুতে আইডোকলগুলিতে কলামগুলি রাখার জন্য: আইডাকলগুলি <- c ("নাম", "আইডি 2", "শুরু", "সময়কাল"); কলাম <- সি (আইডকোল, নাম (সিটি)) [- যা (নাম (সিটি)% আইডিকোলে)%)]); ডিএফ <- ডিএফ [
কলস

13
@ ইউজার 4050: আপনি কয়টি df[,c(1,3,2,4:ncol(df))]কলামগুলি জানেন না তা যখন আপনি ব্যবহার করতে পারেন ।
arekolek

1
আপনি ডিপুট (কলনেম (ডিএফ)) ব্যবহার করতে পারেন, এটি আর অক্ষরের বিন্যাসে কলামের নাম মুদ্রণ করে। এরপরে আপনি নামগুলি পুনর্বিন্যাস করতে পারেন।
ক্রিস

168
# reorder by column name
data <- data[c("A", "B", "C")]

#reorder by column index
data <- data[c(1,3,2)]

1
একটি শিক্ষানবিস হিসাবে প্রশ্ন, আপনি সূচক এবং নাম দিয়ে ক্রম একত্রিত করতে পারেন? যেমন data <- data[c(1,3,"Var1", 2)]?
ব্রাম ভ্যানরোয়

6
@ ব্র্যামভ্যানরোয় নোপ, c(1,3,"Var1", 2)পড়তে হবে c("1","3","Var1", "2")কারণ ভেক্টরগুলিতে কেবলমাত্র এক প্রকারের ডেটা থাকতে পারে, সুতরাং প্রকারগুলি সবচেয়ে সাধারণ ধরণের উপস্থিতিতে প্রচারিত হয়। "1", "3" ইত্যাদি অক্ষরের নাম সহ কোনও কলাম নেই বলে আপনি "অপরিজ্ঞাত কলাম" পেয়ে যাবেন। list(1,3,"Var1", 2)প্রকার প্রচার ছাড়াই মান রাখে, তবে আপনি listউপরের প্রসঙ্গে একটি ব্যবহার করতে পারবেন না ।
টেরি ব্রাউন

1
কেন mtcars[c(1,3,2)]সাবসেটিং কাজ করে? আমি ভুল মাত্রা বা অনুরূপ সম্পর্কিত একটি ত্রুটি আশা করা উচিত ... এটি করা উচিত নয় mtcars[,c(1,3,2)]?
ল্যান্ড্রোনি


106

আপনি সাবসেট ফাংশনটিও ব্যবহার করতে পারেন:

data <- subset(data, select=c(3,2,1))

অন্যান্য উত্তরের মতো আপনার [অপারেটর] আরও ভাল ব্যবহার করা উচিত তবে আপনি একক কমান্ডে একটি উপসেট এবং একটি কলাম পুনরায় অর্ডার অপারেশন করতে পারেন তা জেনে রাখা দরকারী useful

হালনাগাদ:

আপনি dplyr প্যাকেজ থেকে নির্বাচিত ফাংশনটি ব্যবহার করতে পারেন:

data = data %>% select(Time, out, In, Files)

আমি দক্ষতা সম্পর্কে নিশ্চিত নই, তবে ডিপিপ্লায়ার সিনট্যাক্সের জন্য ধন্যবাদ এই সমাধানটি আরও নমনীয় হওয়া উচিত, বিশেষত আপনার যদি প্রচুর কলাম থাকে। উদাহরণস্বরূপ, নিম্নলিখিতগুলি বিপরীত ক্রমে mtcars ডেটাসেটের কলামগুলি পুনঃক্রম করবে:

mtcars %>% select(carb:mpg)

এবং নিম্নলিখিতগুলি কেবল কয়েকটি কলাম পুনরায় অর্ডার করবে এবং অন্যান্যগুলি বাতিল করবে:

mtcars %>% select(mpg:disp, hp, wt, gear:qsec, starts_with('carb'))

Dplyr এর নির্বাচিত বাক্য গঠন সম্পর্কে আরও পড়ুন ।


5
ব্যবহার না করার কিছু কারণ রয়েছে subset(), এই প্রশ্নটি দেখুন
মেরোজ

2
ধন্যবাদ. যে কোনও ক্ষেত্রে আমি এখন সাবসেটের পরিবর্তে ডিপিপ্লায়ার প্যাকেজ থেকে নির্বাচিত ফাংশনটি ব্যবহার করব।
ডালোলিওগম

87
আপনি যখন বাম দিকে কয়েকটি কলাম আনতে চান এবং অন্যগুলি না নামান, আমি everything()বিশেষত দুর্দান্ত দেখতে পাই ; mtcars %>% select(wt, gear, everything())
গায়াবেল

2
ডান / প্রান্তে কলামগুলি পুনরায় সাজানোর জন্য সমস্ত কিছু () সিলেক্ট হেল্পার ফাংশনটি ব্যবহার করার অন্য উপায় way stackoverflow.com/a/44353144/4663008 github.com/tidyverse/dplyr/issues/2838 মত ব্যবহার করার অধিকার শেষ এবং বাঁদিকে অন্যদের কাছে কিছু কলাম সরাতে 2 নির্বাচন করুন () 's করতে হবে মনে হয়।
আর্থার ইপ

1
new ফাংশন dplyr :: স্থানান্তর ঠিক এর জন্য। নীচের এইচ 1 এর উত্তর দেখুন
আর্থার ইপ

39

এই মন্তব্যে যেমন উল্লেখ করা হয়েছে , একটিতে কলামগুলি পুনরায় অর্ডার করার জন্য স্ট্যান্ডার্ড পরামর্শগুলি data.frameসাধারণত জটিল এবং ত্রুটি-প্রবণ, বিশেষত যদি আপনার প্রচুর কলাম থাকে।

এই ফাংশনটি অবস্থান অনুসারে কলামগুলি পুনরায় সাজানোর অনুমতি দেয়: একটি চলক নাম এবং পছন্দসই অবস্থান নির্দিষ্ট করুন এবং অন্যান্য কলামগুলির বিষয়ে চিন্তা করবেন না।

##arrange df vars by position
##'vars' must be a named vector, e.g. c("var.name"=1)
arrange.vars <- function(data, vars){
    ##stop if not a data.frame (but should work for matrices as well)
    stopifnot(is.data.frame(data))

    ##sort out inputs
    data.nms <- names(data)
    var.nr <- length(data.nms)
    var.nms <- names(vars)
    var.pos <- vars
    ##sanity checks
    stopifnot( !any(duplicated(var.nms)), 
               !any(duplicated(var.pos)) )
    stopifnot( is.character(var.nms), 
               is.numeric(var.pos) )
    stopifnot( all(var.nms %in% data.nms) )
    stopifnot( all(var.pos > 0), 
               all(var.pos <= var.nr) )

    ##prepare output
    out.vec <- character(var.nr)
    out.vec[var.pos] <- var.nms
    out.vec[-var.pos] <- data.nms[ !(data.nms %in% var.nms) ]
    stopifnot( length(out.vec)==var.nr )

    ##re-arrange vars by position
    data <- data[ , out.vec]
    return(data)
}

এখন ওপি-র অনুরোধটি এর মতো সহজ হয়ে উঠেছে:

table <- data.frame(Time=c(1,2), In=c(2,3), Out=c(3,4), Files=c(4,5))
table
##  Time In Out Files
##1    1  2   3     4
##2    2  3   4     5

arrange.vars(table, c("Out"=2))
##  Time Out In Files
##1    1   3  2     4
##2    2   4  3     5

অতিরিক্তভাবে অদলবদল Timeএবং Filesকলামগুলি আপনি এটি করতে পারেন:

arrange.vars(table, c("Out"=2, "Files"=1, "Time"=4))
##  Files Out In Time
##1     4   3  2    1
##2     5   4  3    2

খুব সুন্দর ফাংশন। আমি আমার ব্যক্তিগত প্যাকেজে এই ফাংশনের একটি পরিবর্তিত সংস্করণ যুক্ত করেছি ।
ডিলিট

1
এটি সত্যিই দরকারী - এটি আমার অনেক সময় বাঁচাতে চলেছে যখন আমি কেবল একটি কলামটি সত্যিকারের প্রশস্ত সঙ্কটের প্রান্ত থেকে শুরুতে নিয়ে যেতে চাই
মিঃমোলেজে

বাহ, আমি এই ভালবাসি।
অফজুরস্কি

37

একটি dplyrসমাধান ( tidyverseপ্যাকেজ সংস্থার অংশ ) ব্যবহার করা হয় select:

select(table, "Time", "Out", "In", "Files") 

# or

select(table, Time, Out, In, Files)

2
আমার জন্য সেরা বিকল্প। এমনকি যদি এটি ইনস্টল করতে হয় তবে এটি স্পষ্টভাবে সম্ভাবনা।
গারিনী

15
Tidyverse (আসলে dplyr) ও সামনে প্রজাতি পরিবর্তনশীল সরাতে, কলাম দলের নির্বাচন করতে উদাহরণস্বরূপ বিকল্প আছে: select(iris, Species, everything())। এছাড়াও লক্ষ করুন যে উদ্ধৃতিগুলির প্রয়োজন নেই।
পল রৌগিয়াক্স 16'18

3
এটি লক্ষণীয় যে এটি everything()পলরোগিউক্সের মন্তব্য হিসাবে অন্তর্ভুক্ত না করা হলে এটি সমস্ত কলামগুলি স্পষ্টভাবে সুনির্দিষ্টভাবে নামিয়ে দেবে
ডিবিবিয়ান

dplyrএর groupভেরিয়েবলগুলিও পুনরায় সাজানো হবে, সুতরাং চেইনে এটি ব্যবহার করার সময় নজর রাখুন।
ডেভিড টোনহোফার

26

হতে পারে এটি কাকতালীয় যে কলামের ক্রমটি আপনি চান তা বর্ণমালু ক্রমে অবতরণ করে কলামের নাম থাকতে পারে। যেহেতু আপনি কেবল এটি করতে পারেন:

df<-df[,order(colnames(df),decreasing=TRUE)]

যখন আমার কাছে অনেকগুলি কলাম সহ বড় ফাইল থাকে আমি এটি ব্যবহার করি।


!! WARNING !! data.tableTARGETকোনও আন্ত ভেক্টরে পরিণত হয়: TARGET <- TARGET[ , order(colnames(TARGET), decreasing=TRUE)] এটি ঠিক করার জন্য: TARGET <- as.data.frame(TARGET) TARGET <- TARGET[ , order(colnames(TARGET), decreasing=TRUE)]
জাচারি রায়ান স্মিথ


12

তিন উপরের বিপরিতে উত্তর একটি দুর্বলতা আছে।

আপনার ডেটাফ্রেমটি যদি এমন দেখাচ্ছে

df <- data.frame(Time=c(1,2), In=c(2,3), Out=c(3,4), Files=c(4,5))

> df
  Time In Out Files
1    1  2   3     4
2    2  3   4     5

তাহলে এটি ব্যবহারের একটি দুর্বল সমাধান

> df2[,c(1,3,2,4)]

এটি কাজ করে, তবে আপনি কেবল আপনার ইনপুটটিতে কলামগুলির ক্রমের উপর নির্ভরতা প্রবর্তন করেছেন।

ভঙ্গুর প্রোগ্রামিংয়ের এই স্টাইলটি এড়ানো উচিত।

কলামগুলির স্পষ্ট নামকরণ একটি আরও ভাল সমাধান

data[,c("Time", "Out", "In", "Files")]

এছাড়াও, আপনি যদি আরও সাধারণ সেটিংয়ে আপনার কোডটি পুনরায় ব্যবহার করতে চান তবে আপনি সহজভাবেই পারেন

out.column.name <- "Out"
in.column.name <- "In"
data[,c("Time", out.column.name, in.column.name, "Files")]

এটি বেশ সুন্দর কারণ এটি পুরোপুরি আক্ষরিককে বিচ্ছিন্ন করে। বিপরীতে, আপনি dplyr এর ব্যবহার করেselect

data <- data %>% select(Time, out, In, Files)

তারপরে আপনি তাদের সেট আপ করবেন যারা আপনার কোডটি পরে পড়বেন, নিজেকে অন্তর্ভুক্ত রেখেছিলেন, কিছুটা প্রতারনার জন্য। কলামের নামগুলি কোডটিতে যেমন প্রদর্শিত না হয়ে আক্ষরিক হিসাবে ব্যবহৃত হচ্ছে।


3

dplyrসংস্করণে কলামগুলি সহজেই পুনঃক্রম করতে ফাংশন 1.0.0অন্তর্ভুক্ত রয়েছে relocate():

dat <- data.frame(Time=c(1,2), In=c(2,3), Out=c(3,4), Files=c(4,5))

library(dplyr) # from version 1.0.0 only

dat %>%
  relocate(Out, .before = In)

অথবা

dat %>%
  relocate(Out, .after = Time)


1

শুধুমাত্র এক আমি কাজ ঠিকই দেখেছ থেকে এখানে

 shuffle_columns <- function (invec, movecommand) {
      movecommand <- lapply(strsplit(strsplit(movecommand, ";")[[1]],
                                 ",|\\s+"), function(x) x[x != ""])
  movelist <- lapply(movecommand, function(x) {
    Where <- x[which(x %in% c("before", "after", "first",
                              "last")):length(x)]
    ToMove <- setdiff(x, Where)
    list(ToMove, Where)
  })
  myVec <- invec
  for (i in seq_along(movelist)) {
    temp <- setdiff(myVec, movelist[[i]][[1]])
    A <- movelist[[i]][[2]][1]
    if (A %in% c("before", "after")) {
      ba <- movelist[[i]][[2]][2]
      if (A == "before") {
        after <- match(ba, temp) - 1
      }
      else if (A == "after") {
        after <- match(ba, temp)
      }
    }
    else if (A == "first") {
      after <- 0
    }
    else if (A == "last") {
      after <- length(myVec)
    }
    myVec <- append(temp, values = movelist[[i]][[1]], after = after)
  }
  myVec
}

এটি ব্যবহার করুন:

new_df <- iris[shuffle_columns(names(iris), "Sepal.Width before Sepal.Length")]

একটি যাদুমন্ত্র মত কাজ করে.

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