প্রতিটি সারি ডেটা পুনরাবৃত্তি করুন a একটি কলামে নির্দিষ্ট সময়ের সংখ্যা ফ্রেম করুন


150
df <- data.frame(var1 = c('a', 'b', 'c'), var2 = c('d', 'e', 'f'),
                 freq = 1:3)

উপরের ডাটা.ফ্রেমের প্রথম দুটি কলাম প্রতিটি সারি প্রসারিত করার সহজ উপায় কী, যাতে প্রতিটি সারিতে 'ফ্রিক' কলামে উল্লিখিত সময়ের সংখ্যাটি পুনরাবৃত্তি হয়?

অন্য কথায়, এটি থেকে যান:

df
  var1 var2 freq
1    a    d    1
2    b    e    2
3    c    f    3

এটি:

df.expanded
  var1 var2
1    a    d
2    b    e
3    b    e
4    c    f
5    c    f
6    c    f

উত্তর:


169

এখানে একটি সমাধান রয়েছে:

df.expanded <- df[rep(row.names(df), df$freq), 1:2]

ফলাফল:

    var1 var2
1      a    d
2      b    e
2.1    b    e
3      c    f
3.1    c    f
3.2    c    f

গ্রেট! আমি সর্বদা ভুলে যাই আপনি এইভাবে বর্গাকার বন্ধনী ব্যবহার করতে পারেন। আমি কেবলমাত্র সাবসেটিং বা পুনঃক্রম করার জন্য সূচীকরণের কথা ভাবছি। আমার আরও একটি সমাধান ছিল যা অনেক কম মার্জিত এবং সন্দেহ নেই যে কম দক্ষ। আমি অন্যভাবে তুলনা করতে যাতে যাইহোক পোস্ট করতে পারে।
wkmor1

22
বৃহত্তর জন্য data.frameআরও কার্যকর row.names(df)সঙ্গে seq.int(1,nrow(df))বা প্রতিস্থাপন হয় seq_len(nrow(df))
মেরেক

এটি একটি বিশাল ডেটা ফ্রেমের জন্য দুর্দান্তভাবে কাজ করেছে - 1.5 মিলিয়ন সারি, 5 টি কলস, খুব দ্রুত চলে গেছে। ধন্যবাদ!
গাব

4
1: 2 হার্ড কোডগুলি উদাহরণের এই সমাধানটির সমাধান করে, 1: এনকোল (ডিএফ) একটি স্বেচ্ছাচারিত ডেটাফ্রেমের জন্য কাজ করবে।
ভ্লাদিম

71

পুরানো প্রশ্ন, পরিপাটি করা নতুন ক্রিয়া:

library(tidyr) # version >= 0.8.0
df <- data.frame(var1=c('a', 'b', 'c'), var2=c('d', 'e', 'f'), freq=1:3)
df %>% 
  uncount(freq)

    var1 var2
1      a    d
2      b    e
2.1    b    e
3      c    f
3.1    c    f
3.2    c    f

2
একটি পরিপাটি সমাধানের জন্য ধন্যবাদ। এই জাতীয় সমাধানগুলি সাধারণত "সরল" এবং পাঠযোগ্য of
ডি উডস

45

প্যাকেজ expandRows()থেকে ব্যবহার করুন splitstackshape:

library(splitstackshape)
expandRows(df, "freq")

সাধারণ বাক্য গঠন, খুব দ্রুত, এর উপর data.frameবা কাজ করে data.table

ফলাফল:

    var1 var2
1      a    d
2      b    e
2.1    b    e
3      c    f
3.1    c    f
3.2    c    f

23

@ নিলফিউজ এর সমাধান এস এর পক্ষে দুর্দান্ত কাজ করে data.frameতবে data.tableতাদের পক্ষে row.namesসম্পত্তিটির অভাব হওয়ায় তা নয় । এই পদ্ধতির উভয়ের জন্য কাজ করে:

df.expanded <- df[rep(seq(nrow(df)), df$freq), 1:2]

এর কোডটি data.tableএকটি বাচ্চা ক্লিনার:

# convert to data.table by reference
setDT(df)
df.expanded <- df[rep(seq(.N), freq), !"freq"]

4
অন্য বিকল্প:df[rep(seq(.N), freq)][, freq := NULL]
জাপ

অন্য বিকল্পdf[rep(1:.N, freq)][, freq:=NULL]
ডেল কুবে

4

যদি আপনাকে খুব বড় ডেটাতে এই অপারেশনটি করতে হয় তবে ফ্রেমগুলিকে আমি একটি ডেটাতে রূপান্তর করার পরামর্শ দেব। টেবিল এবং নীচেরটি ব্যবহার করুন যা খুব দ্রুত চালানো উচিত:

library(data.table)
dt <- data.table(df)
dt.expanded <- dt[ ,list(freq=rep(1,freq)),by=c("var1","var2")]
dt.expanded[ ,freq := NULL]
dt.expanded

এই সমাধানটি কত দ্রুত দেখুন:

df <- data.frame(var1=1:2e3, var2=1:2e3, freq=1:2e3)
system.time(df.exp <- df[rep(row.names(df), df$freq), 1:2])
##    user  system elapsed 
##    4.57    0.00    4.56
dt <- data.table(df)
system.time(dt.expanded <- dt[ ,list(freq=rep(1,freq)),by=c("var1","var2")])
##    user  system elapsed 
##    0.05    0.01    0.06

আমি কোনো ত্রুটির সম্মুখীন হয়েছেন: Error in rep(1, freq) : invalid 'times' argument। এবং প্রদত্ত যে এখানে ইতিমধ্যে একটি ডেটা রয়েছে able এই প্রশ্নের উত্তর যোগ্য, আপনি কীভাবে আপনার দৃষ্টিভঙ্গি আলাদা বা বর্তমান ডেটা-টেবিল উত্তরের চেয়ে আরও ভাল তা বর্ণনা করতে চাইতে পারেন। বা যদি কোনও বড় পার্থক্য না হয় তবে আপনি পরিবর্তে বিদ্যমান উত্তরের মন্তব্য হিসাবে এটি যুক্ত করতে পারেন।
স্যাম ফিরকে

@ সামফির্ক: আপনার মন্তব্যের জন্য আপনাকে ধন্যবাদ। আজব, আমি এটি আবার চেষ্টা করেছি এবং আমি এরকম কোনও ত্রুটি পাই না। আপনি কি dfওপির প্রশ্ন থেকে মূলটি ব্যবহার করবেন ? আমার উত্তরটি আরও ভাল কারণ অন্য উত্তরটি সিনট্যাক্স data.tableব্যবহার করে প্যাকেজটির অপব্যবহারের এক প্রকারের data.frameপ্রশ্নাবলী দেখুন data.table: "নাম পরিবর্তে সংখ্যায় কলামগুলি উল্লেখ করা সাধারণত খারাপ অভ্যাস।"
ভনজড

1
ব্যাখ্যার জন্য ধন্যবাদ. আপনার কোডটি dfওপি দ্বারা পোস্ট করা নমুনায় আমার জন্য কাজ করে, তবে যখন আমি এটি একটি বৃহত্তর ডেটা-ফ্রেমে বেনমার্ক করার চেষ্টা করি তখন আমি সেই ত্রুটি পেয়েছি। আমি ব্যবহৃত ডেটা ফ্রেমটি ছিল: set.seed(1) dfbig <- data.frame(var1=sample(letters, 1000, replace = TRUE), var2=sample(LETTERS, 1000, replace = TRUE), freq=sample(1:10, 1000, replace = TRUE)) ক্ষুদ্র ডাটা.ফ্রেমে, বেস উত্তরটি আমার বেঞ্চমার্কিংয়ে ভাল করে, এটি কেবল বড় ডেটা ফ্রেমগুলিতে ভাল স্কেল করে না। অন্য তিনটি উত্তর এই বৃহত্তর ডেটা ফ্রেমটির সাথে সাফল্যের সাথে চলেছিল।
স্যাম ফিরকে

@ সামফির্ক: এটি সত্যই অদ্ভুত, এটিও সেখানে কাজ করা উচিত এবং কেন হয় না তা আমি জানি না। আপনি কি এটি থেকে একটি প্রশ্ন তৈরি করতে চান বা আমি করব?
ভোঞ্জড

ভাল ধারণা. পারবে তুমি? আমি data.tableসিনট্যাক্স জানি না তাই উত্তরগুলি বিচার করার মতো আমার হওয়া উচিত নয়।
স্যাম ফিরকে

4

আর প্রতিটি dplyrবিকল্প sliceযেখানে আমরা প্রতিটি সারিতে সংখ্যার freqবার বার করি

library(dplyr)

df %>%  
  slice(rep(seq_len(n()), freq)) %>% 
  select(-freq)

#  var1 var2
#1    a    d
#2    b    e
#3    b    e
#4    c    f
#5    c    f
#6    c    f

seq_len(n()) অংশটি নিম্নলিখিত যে কোনওটির সাথে প্রতিস্থাপন করা যেতে পারে।

df %>% slice(rep(1:nrow(df), freq)) %>% select(-freq)
#Or
df %>% slice(rep(row_number(), freq)) %>% select(-freq)
#Or
df %>% slice(rep(seq_len(nrow(.)), freq)) %>% select(-freq)

2

আরেকটি সম্ভাবনা ব্যবহার করা হচ্ছে tidyr::expand:

library(dplyr)
library(tidyr)

df %>% group_by_at(vars(-freq)) %>% expand(temp = 1:freq) %>% select(-temp)
#> # A tibble: 6 x 2
#> # Groups:   var1, var2 [3]
#>   var1  var2 
#>   <fct> <fct>
#> 1 a     d    
#> 2 b     e    
#> 3 b     e    
#> 4 c     f    
#> 5 c     f    
#> 6 c     f

ভনজডির উত্তরের এক-লাইন সংস্করণ :

library(data.table)

setDT(df)[ ,list(freq=rep(1,freq)),by=c("var1","var2")][ ,freq := NULL][]
#>    var1 var2
#> 1:    a    d
#> 2:    b    e
#> 3:    b    e
#> 4:    c    f
#> 5:    c    f
#> 6:    c    f

2019-05-21 তারিখে ডিপেক্স প্যাকেজ (v0.2.1) দ্বারা তৈরি করা হয়েছে


1

আমি জানি এটি কেস নয় তবে আপনার যদি মূল ফ্রিক কলামটি রাখা দরকার হয় তবে আপনি আরও একটি tidyverseপদ্ধতির সাথে একত্রে ব্যবহার করতে পারেন rep:

library(purrr)

df <- data.frame(var1 = c('a', 'b', 'c'), var2 = c('d', 'e', 'f'), freq = 1:3)

df %>% 
  map_df(., rep, .$freq)
#> # A tibble: 6 x 3
#>   var1  var2   freq
#>   <fct> <fct> <int>
#> 1 a     d         1
#> 2 b     e         2
#> 3 b     e         2
#> 4 c     f         3
#> 5 c     f         3
#> 6 c     f         3

2019-12-21 তারিখে ডিপেক্স প্যাকেজ (v0.3.0) দ্বারা তৈরি


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