আর তে কোনও ভেক্টরকে অংশগুলিতে বিভক্ত করুন


227

আমাকে কোনও ভেক্টরকে আর সমান আকারের এন অংশগুলিতে বিভক্ত করতে হবে to এটি করার জন্য কোনও বেস ফাংশন আমি খুঁজে পেলাম না। এছাড়াও গুগল আমাকে কোথাও পায় নি। সুতরাং এখানে আমি যা নিয়ে এসেছি, আশা করি এটি কারও কারও কাছে সহায়তা করে।

x <- 1:10
n <- 3
chunk <- function(x,n) split(x, factor(sort(rank(x)%%n)))
chunk(x,n)
$`0`
[1] 1 2 3

$`1`
[1] 4 5 6 7

$`2`
[1]  8  9 10

যে কোনও মন্তব্য, পরামর্শ বা উন্নতি সত্যই স্বাগত এবং প্রশংসা করা হয়।

চিয়ার্স, সেবাস্তিয়ান


5
হ্যাঁ, এটি অত্যন্ত অস্পষ্ট যে আপনি যা পাবেন তা হ'ল "সমান আকারের অংশ" এর সমাধান। তবে সম্ভবত এটি আপনাকে সেখানে পেয়েছে: x <- 1:10; n <- 3; বিভক্ত (এক্স, কাটা (এক্স, এন, লেবেলগুলি = মিথ্যা))
এমডসুমনার

প্রশ্নের ভলিউম এবং পূর্ববর্তী মন্তব্যে সমাধান উভয়ই ভুল, কারণ ভেক্টর যদি বারবার এন্ট্রি করে থাকে তবে তারা কাজ করতে পারে না। এটি চেষ্টা করুন:> ফু <- সি (রেপ (1, 12), রেপ (2,3), রেপ (3,3%) [1] 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 3 3 3 3> খণ্ড (ফু, 2) (ভুল ফলাফল দেয়)> খণ্ড (
ফু

(পূর্ববর্তী মন্তব্য অবিরত) কেন? র‌্যাঙ্ক (এক্স) এর পূর্ণসংখ্যার> র‌্যাঙ্ক (সি (1,1,2,3)) হওয়া প্রয়োজন হয় না [1] 1.5 1.5 3.0 4.0 তাই প্রশ্নটির পদ্ধতিটি ব্যর্থ হয়। এইটি কাজ করে (নীচে হারলানকে ধন্যবাদ)> চিঙ্ক 2 <- ফাংশন (এক্স, এন) বিভাজন (এক্স, কাট (সেক_আলং (এক্স), এন, লেবেল = মিথ্যা))
ম্যাথহেডিংক্লাউডস

2
> বিভক্ত (ফু, কাটা (
ফু

1
যেমন @ মাথহেডইনক্লাউডস পরামর্শ দেয়, উদাহরণস্বরূপ ডেটা একটি খুব বিশেষ কেস। উদাহরণস্বরূপ যেগুলি বেশি সাধারণ হয় সেগুলি আরও কার্যকর এবং আরও ভাল পরীক্ষা হবে। উদাহরণস্বরূপ x <- c(NA, 4, 3, NA, NA, 2, 1, 1, NA ); y <- letters[x]; z <- factor(y)অনুপস্থিত ডেটা, পুনরাবৃত্ত মানগুলির উদাহরণ দেয় যা ইতিমধ্যে সাজানো হয়নি এবং বিভিন্ন শ্রেণিতে রয়েছে (পূর্ণসংখ্যা, চরিত্র, গুণক)।
কালিন

উত্তর:


313

একটি এক-রেখার বিভাজক ডি আকার 20 এর অংশে বিভক্ত:

split(d, ceiling(seq_along(d)/20))

আরো বিস্তারিত: আমার মনে হয় আপনার প্রয়োজন হয় seq_along(), split()এবং ceiling():

> d <- rpois(73,5)
> d
 [1]  3  1 11  4  1  2  3  2  4 10 10  2  7  4  6  6  2  1  1  2  3  8  3 10  7  4
[27]  3  4  4  1  1  7  2  4  6  0  5  7  4  6  8  4  7 12  4  6  8  4  2  7  6  5
[53]  4  5  4  5  5  8  7  7  7  6  2  4  3  3  8 11  6  6  1  8  4
> max <- 20
> x <- seq_along(d)
> d1 <- split(d, ceiling(x/max))
> d1
$`1`
 [1]  3  1 11  4  1  2  3  2  4 10 10  2  7  4  6  6  2  1  1  2

$`2`
 [1]  3  8  3 10  7  4  3  4  4  1  1  7  2  4  6  0  5  7  4  6

$`3`
 [1]  8  4  7 12  4  6  8  4  2  7  6  5  4  5  4  5  5  8  7  7

$`4`
 [1]  7  6  2  4  3  3  8 11  6  6  1  8  4

34
প্রশ্নটি nসমান আকারের অংশগুলির জন্য জিজ্ঞাসা করে । এটি আপনাকে আকারের অজানা সংখ্যায় পেয়েছে n। আমার একই সমস্যা ছিল এবং @ মথহেডিংক্লাউডস থেকে সমাধানগুলি ব্যবহার করেছি।
rrs

4
যেমন কেউ ডি 1 এর আউটপুট থেকে দেখতে পাচ্ছে, এই উত্তরটি d টি সমান আকারের গ্রুপগুলিতে বিভক্ত হয় না (4 অবশ্যই সংক্ষিপ্ত) is সুতরাং এটি প্রশ্নের উত্তর দেয় না।
ক্যালিমো

9
@rrs: বিভক্ত (ঘ, সিলিং (seq_along (ঘ) / (দৈর্ঘ্য (ঘ) / ঢ)))
gkcn

আমি জানি এটি বেশ পুরানো তবে যারা এখানে হোঁচট খায় তাদের পক্ষে এটি সহায়ক হতে পারে। যদিও ওপির প্রশ্নটি ছিল সমান আকারের অংশগুলিতে বিভক্ত হওয়া, যদি ভেক্টরটি বিভাজকের একাধিক হিসাবে না ঘটে, তবে শেষ চিংকের অংশটির চেয়ে আলাদা আকার থাকবে। n-chunksআমি বিভক্ত করতে বিভক্ত max <- length(d)%/%n। আমি এটি 31 টি স্ট্রিংয়ের ভেক্টর দিয়ে ব্যবহার করেছি এবং 10 টি বাক্যের 3 ভেক্টরের একটি তালিকা এবং 1 বাক্যটির একটি পেয়েছি।
সালভু


36
simplified version...
n = 3
split(x, sort(x%%n))

আমি এটি পছন্দ করি কারণ এটি আপনাকে যতটা সম্ভব সমান আকারের অংশগুলি দেয় (বড় টাস্ককে ভাগ করার জন্য ভাল যেমন সীমিত র‌্যামের সমন্বয় করা বা একাধিক থ্রেড জুড়ে একটি টাস্ক চালানো)।
এলেক্সভিপিকারিং

3
এটি দরকারী, তবে মনে রাখবেন এটি কেবল সংখ্যা ভেক্টরগুলিতে কাজ করবে।
কিথ হুগিট

@ কীথ হুইট এই বিষয়গুলির সাথে সমাধান করা যেতে পারে এবং স্তরগুলি সংখ্যাসূচক হিসাবে ফিরে আসতে পারে। বা কমপক্ষে এটি আমি এটি বাস্তবায়ন করেছি।
ড্রামারোড

20

Ggplot2 ফাংশনটি ব্যবহার করে দেখুন cut_number:

library(ggplot2)
x <- 1:10
n <- 3
cut_number(x, n) # labels = FALSE if you just want an integer result
#>  [1] [1,4]  [1,4]  [1,4]  [1,4]  (4,7]  (4,7]  (4,7]  (7,10] (7,10] (7,10]
#> Levels: [1,4] (4,7] (7,10]

# if you want it split into a list:
split(x, cut_number(x, n))
#> $`[1,4]`
#> [1] 1 2 3 4
#> 
#> $`(4,7]`
#> [1] 5 6 7
#> 
#> $`(7,10]`
#> [1]  8  9 10

2
এই বিভাজন জন্য কাজ করে না আপ x, yঅথবা zসংজ্ঞায়িত এই মন্তব্যটি । বিশেষত, এটি ফলাফলগুলি বাছাই করে, যা প্রয়োগের উপর নির্ভর করে ঠিক আছে বা নাও হতে পারে।
কালিন


18

এটি আপনার যা আছে তার থেকে এটি আলাদাভাবে বিভক্ত হবে, তবে এখনও আমার মনে হয় এটি একটি দুর্দান্ত তালিকা কাঠামো:

chunk.2 <- function(x, n, force.number.of.groups = TRUE, len = length(x), groups = trunc(len/n), overflow = len%%n) { 
  if(force.number.of.groups) {
    f1 <- as.character(sort(rep(1:n, groups)))
    f <- as.character(c(f1, rep(n, overflow)))
  } else {
    f1 <- as.character(sort(rep(1:groups, n)))
    f <- as.character(c(f1, rep("overflow", overflow)))
  }

  g <- split(x, f)

  if(force.number.of.groups) {
    g.names <- names(g)
    g.names.ordered <- as.character(sort(as.numeric(g.names)))
  } else {
    g.names <- names(g[-length(g)])
    g.names.ordered <- as.character(sort(as.numeric(g.names)))
    g.names.ordered <- c(g.names.ordered, "overflow")
  }

  return(g[g.names.ordered])
}

আপনি কীভাবে এটি ফর্ম্যাট করতে চান তার উপর নির্ভর করে যা আপনাকে নিম্নলিখিতটি দেবে:

> x <- 1:10; n <- 3
> chunk.2(x, n, force.number.of.groups = FALSE)
$`1`
[1] 1 2 3

$`2`
[1] 4 5 6

$`3`
[1] 7 8 9

$overflow
[1] 10

> chunk.2(x, n, force.number.of.groups = TRUE)
$`1`
[1] 1 2 3

$`2`
[1] 4 5 6

$`3`
[1]  7  8  9 10

এই সেটিংসটি ব্যবহার করে বেশ কয়েকটি সময় চালানো হচ্ছে:

set.seed(42)
x <- rnorm(1:1e7)
n <- 3

তারপরে আমাদের নিম্নলিখিত ফলাফল রয়েছে:

> system.time(chunk(x, n)) # your function 
   user  system elapsed 
 29.500   0.620  30.125 

> system.time(chunk.2(x, n, force.number.of.groups = TRUE))
   user  system elapsed 
  5.360   0.300   5.663 

সম্পাদনা: আমার ফাংশনে as.factor () থেকে as.character () এ পরিবর্তন করা এটিকে দ্বিগুণ দ্রুত করেছে।


13

গাদা আরও কয়েকটি বৈকল্পিক ...

> x <- 1:10
> n <- 3

দ্রষ্টব্য, factorএখানে আপনার এখানে ফাংশনটি ব্যবহার করার দরকার নেই, তবে আপনি এখনও sortআপনার প্রথম ভেক্টরটি o / w করতে চান 1 2 3 10:

> chunk <- function(x, n) split(x, sort(rank(x) %% n))
> chunk(x,n)
$`0`
[1] 1 2 3
$`1`
[1] 4 5 6 7
$`2`
[1]  8  9 10

বা আপনি উপরের বাম টিকগুলিতে সংখ্যাগুলি সহ, অক্ষর সূচকগুলি নির্ধারণ করতে পারেন:

> my.chunk <- function(x, n) split(x, sort(rep(letters[1:n], each=n, len=length(x))))
> my.chunk(x, n)
$a
[1] 1 2 3 4
$b
[1] 5 6 7
$c
[1]  8  9 10

অথবা আপনি কোনও ভেক্টরে সঞ্চিত প্লেয়ারওয়ার্ড নাম ব্যবহার করতে পারেন। নোট করুন যে বর্ণমালাগুলিতে sortক্রমাগত মান পেতে xলেবেলগুলি ব্যবহার করে:

> my.other.chunk <- function(x, n) split(x, sort(rep(c("tom", "dick", "harry"), each=n, len=length(x))))
> my.other.chunk(x, n)
$dick
[1] 1 2 3
$harry
[1] 4 5 6
$tom
[1]  7  8  9 10

12

বেস আর এর ব্যবহার rep_len:

x <- 1:10
n <- 3

split(x, rep_len(1:n, length(x)))
# $`1`
# [1]  1  4  7 10
# 
# $`2`
# [1] 2 5 8
# 
# $`3`
# [1] 3 6 9

এবং ইতিমধ্যে উল্লিখিত হিসাবে যদি আপনি সাজানো সূচকগুলি চান, কেবল:

split(x, sort(rep_len(1:n, length(x))))
# $`1`
# [1] 1 2 3 4
# 
# $`2`
# [1] 5 6 7
# 
# $`3`
# [1]  8  9 10

9

আপনি বিভাজন / কাটা একত্রিত করতে পারেন, এমডিএসএমারের পরামর্শ অনুসারে, এমনকি গোষ্ঠীগুলি তৈরি করতে কোয়ান্টাইল সহ:

split(x,cut(x,quantile(x,(0:n)/n), include.lowest=TRUE, labels=FALSE))

এটি আপনার উদাহরণের জন্য একই ফলাফল দেয় তবে স্কিউ ভেরিয়েবলের জন্য নয়।


7

split(x,matrix(1:n,n,length(x))[1:length(x)])

সম্ভবত এটি আরও স্পষ্ট, তবে একই ধারণা:
split(x,rep(1:n, ceiling(length(x)/n),length.out = length(x)))

যদি আপনি এটি অর্ডার করতে চান তবে এটির চারপাশে এক প্রকার ছুঁড়ে দিন


6

আমার একই ফাংশনটির প্রয়োজন ছিল এবং পূর্ববর্তী সমাধানগুলি পড়েছি, তবে আমার শেষেও ভারসাম্যহীন অংশ থাকা দরকার ie যেমন আমার যদি 10 টি উপাদান থাকে তবে সেগুলি 3 টির ভেক্টরগুলিতে বিভক্ত করা যায় তবে আমার ফলাফলটিতে 3, সহ ভেক্টর থাকা উচিত যথাক্রমে ৩,৪ টি উপাদান। সুতরাং আমি নিম্নলিখিতটি ব্যবহার করেছি (পাঠযোগ্যতার জন্য আমি কোডটি অযৌক্তিকভাবে ছেড়েছি, অন্যথায় অনেকগুলি ভেরিয়েবলের দরকার নেই):

chunk <- function(x,n){
  numOfVectors <- floor(length(x)/n)
  elementsPerVector <- c(rep(n,numOfVectors-1),n+length(x) %% n)
  elemDistPerVector <- rep(1:numOfVectors,elementsPerVector)
  split(x,factor(elemDistPerVector))
}
set.seed(1)
x <- rnorm(10)
n <- 3
chunk(x,n)
$`1`
[1] -0.6264538  0.1836433 -0.8356286

$`2`
[1]  1.5952808  0.3295078 -0.8204684

$`3`
[1]  0.4874291  0.7383247  0.5757814 -0.3053884

6

এখানে অন্য বৈকল্পিক।

দ্রষ্টব্য: এই নমুনার সাহায্যে আপনি দ্বিতীয় প্যারামিটারে চুনক সাইজটি নির্দিষ্ট করছেন

  1. সমস্ত খণ্ডগুলি শেষের ব্যতীত অভিন্ন;
  2. সর্বশেষতমটি সবচেয়ে খারাপ আকারের চেয়ে বড় কখনও হবে না never

chunk <- function(x,n)
{
    f <- sort(rep(1:(trunc(length(x)/n)+1),n))[1:length(x)]
    return(split(x,f))
}

#Test
n<-c(1,2,3,4,5,6,7,8,9,10,11)

c<-chunk(n,5)

q<-lapply(c, function(r) cat(r,sep=",",collapse="|") )
#output
1,2,3,4,5,|6,7,8,9,10,|11,|

4

কেবল সূচকগুলি ব্যবহার করে একটি ভেক্টরকে বিভক্ত করার সহজ ফাংশন - এটির বেশি জটিল করার দরকার নেই

vsplit <- function(v, n) {
    l = length(v)
    r = l/n
    return(lapply(1:n, function(i) {
        s = max(1, round(r*(i-1))+1)
        e = min(l, round(r*i))
        return(v[s:e])
    }))
}

3

যদি আপনি পছন্দ না করেন split() এবং আপনি পছন্দ করেন না matrix()(এর ঝোলা এনএগুলির সাথে), এটি এখানে রয়েছে:

chunk <- function(x, n) (mapply(function(a, b) (x[a:b]), seq.int(from=1, to=length(x), by=n), pmin(seq.int(from=1, to=length(x), by=n)+(n-1), length(x)), SIMPLIFY=FALSE))

মত split(), এটি একটি তালিকা ফেরত দেয় তবে এটি লেবেলগুলির সাথে সময় বা স্থান নষ্ট করে না, সুতরাং এটি আরও পারফরম্যান্স হতে পারে।



2

যদি আপনি পছন্দ করেন না split()এবং আপনার এনএগুলি আপনার সংক্ষিপ্ত লেজটি ছিটিয়ে দিতে আপত্তি করে না:

chunk <- function(x, n) { if((length(x)%%n)==0) {return(matrix(x, nrow=n))} else {return(matrix(append(x, rep(NA, n-(length(x)%%n))), nrow=n))} }

প্রত্যাবর্তিত ম্যাট্রিক্সের কলামগুলি ([[, 1: এনসিওল]) আপনি অনুসন্ধান করছেন ড্রয়েড।


2

আমার এমন একটি ফাংশন দরকার যা একটি ডেটা.টেবেলের যুক্তি (উদ্ধৃতিগুলিতে) এবং অন্য যুক্তি যা সেই মূল ডেটা.ট্যাবলের উপগ্রহে সারিগুলির সংখ্যার উপরের সীমা takes এই ফাংশনটি উচ্চতর সীমাটির জন্য যে পরিমাণ সংখ্যক ডেটা তৈরি করে t

library(data.table)    
split_dt <- function(x,y) 
    {
    for(i in seq(from=1,to=nrow(get(x)),by=y)) 
        {df_ <<- get(x)[i:(i + y)];
            assign(paste0("df_",i),df_,inherits=TRUE)}
    rm(df_,inherits=TRUE)
    }

এই ফাংশনটি আমাকে df_ [নাম্বার] নামে একটি ডেটা সিরিজ দেয় আসল তথ্য থেকে শুরু করে সারিতে নামটিতে টেবিল। সর্বশেষ ডেটা.ট্যাবলটি সংক্ষিপ্ত এবং এনএতে পূর্ণ হতে পারে যাতে আপনাকে যে ডেটা বাকী থাকে তার পিছনে সাবসেট করতে হয়। এই জাতীয় ফাংশনটি দরকারী কারণ নির্দিষ্ট জিআইএস সফ্টওয়্যারটির কতগুলি ঠিকানা পিন আপনি আমদানি করতে পারেন তার সীমাবদ্ধতা রয়েছে। সুতরাং ডেটা টেবিলগুলি ছোট অংশগুলিতে টুকরো টুকরো টুকরো টুকরো করার প্রস্তাব দেওয়া যায় না, তবে এটি এড়াতে পারা যায় না।


2

দুঃখিত যদি এই উত্তরটি এত দেরিতে আসে তবে তবে এটি অন্য কারও পক্ষে কার্যকর হতে পারে। প্রকৃতপক্ষে? বিভাজনের শেষে ব্যাখ্যা করা হয়েছে এই সমস্যার খুব কার্যকর সমাধান রয়েছে।

> testVector <- c(1:10) #I want to divide it into 5 parts
> VectorList <- split(testVector, 1:5)
> VectorList
$`1`
[1] 1 6

$`2`
[1] 2 7

$`3`
[1] 3 8

$`4`
[1] 4 9

$`5`
[1]  5 10

3
প্রতিটি গ্রুপে অসম সংখ্যার মান থাকলে এটি ভেঙে যাবে!
মতিফু

2

তবুও আরেকটি সম্ভাবনা splitIndicesপ্যাকেজ থেকে ফাংশন parallel:

library(parallel)
splitIndices(20, 3)

দেয়:

[[1]]
[1] 1 2 3 4 5 6 7

[[2]]
[1]  8  9 10 11 12 13

[[3]]
[1] 14 15 16 17 18 19 20

0

বাহ, এই প্রশ্নটি প্রত্যাশার চেয়ে বেশি ট্রেশন পেয়েছে।

সমস্ত ধারণার জন্য ধন্যবাদ। আমি এই সমাধানটি নিয়ে এসেছি:

require(magrittr)
create.chunks <- function(x, elements.per.chunk){
    # plain R version
    # split(x, rep(seq_along(x), each = elements.per.chunk)[seq_along(x)])
    # magrittr version - because that's what people use now
    x %>% seq_along %>% rep(., each = elements.per.chunk) %>% extract(seq_along(x)) %>% split(x, .) 
}
create.chunks(letters[1:10], 3)
$`1`
[1] "a" "b" "c"

$`2`
[1] "d" "e" "f"

$`3`
[1] "g" "h" "i"

$`4`
[1] "j"

কীটি হ'ল সেক (প্রতিটি = ছান.সাইজ) পরামিতি ব্যবহার করা যাতে এটি কাজ করে। আমার পূর্ববর্তী সমাধানে রেকর্ড (এক্স) এর মতো সিক_আলং ব্যবহার করে, তবে ডুপ্লিকেট এন্ট্রি সহ প্রকৃত ফলাফলটি প্রস্তুত করতে সক্ষম।


সংশ্লিষ্টদের জন্য যে প্রতিনিধি (সেক_আলং (এক্স), প্রতিটি = উপাদান.per.chunk) স্মৃতিতে খুব চাপ দিতে পারে: হ্যাঁ এটি করে does আপনি আমার আগের পরামর্শটির একটি পরিবর্তিত সংস্করণ চেষ্টা করতে পারেন: খণ্ড <- ফাংশন (এক্স, এন) বিভাজন (এক্স, ফ্যাক্টর (সেক_আলং (এক্স) %% এন))
সেবাস্তিয়ান

0

এটি আকার / কে⌋ + 1 বা /n / k⌋ আকারে বিভক্ত হয় এবং ও (এন লগ এন) বাছাই করে না।

get_chunk_id<-function(n, k){
    r <- n %% k
    s <- n %/% k
    i<-seq_len(n)
    1 + ifelse (i <= r * (s+1), (i-1) %/% (s+1), r + ((i - r * (s+1)-1) %/% s))
}

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