নির্দিষ্ট সারি-সূচীতে ডেটাফ্রেমে নতুন সারি যুক্ত করুন, সংযুক্ত নয়?


160

নিম্নলিখিত কোডটি ডেটাফ্রেমের সাথে একটি ভেক্টরকে একত্রিত করে:

newrow = c(1:4)
existingDF = rbind(existingDF,newrow)

তবে এই কোডটি সর্বদা ডেটাফ্রেমের শেষে নতুন সারিটি সন্নিবেশ করে।

আমি কীভাবে ডেটাফ্রেমের মধ্যে একটি নির্দিষ্ট পয়েন্টে সারিটি sertোকাতে পারি? উদাহরণস্বরূপ, যাক ডেটাফ্রেমে 20 টি সারি রয়েছে, আমি কীভাবে 10 এবং 11 সারিগুলির মধ্যে নতুন সারিটি sertোকাতে পারি?


একটি সুবিধাজনক সূচক এবং বাছাই ব্যবহার করবেন?
রোল্যান্ড

22
existingDF = rbind(existingDF[1:10,],newrow,existingDF[-(1:10),])
পোপ

একটি সাধারণ লুপ এবং একটি শর্ত প্রয়োজনের সাথে, সারিগুলি একটি ডেটাফ্রেম থেকে অন্য ডেটাতে যুক্ত করা যায়। একটি নমুনা কোড নীচে দেখানো হয়েছেnewdataframe[nrow(newdataframe)+1,] <- existingdataframe[i,]
'12:56 এ কিরানকোডিফাই করুন

উত্তর:


156

এখানে এমন একটি সমাধান রয়েছে যা (প্রায়শই ধীর) rbindকল এড়ায় :

existingDF <- as.data.frame(matrix(seq(20),nrow=5,ncol=4))
r <- 3
newrow <- seq(4)
insertRow <- function(existingDF, newrow, r) {
  existingDF[seq(r+1,nrow(existingDF)+1),] <- existingDF[seq(r,nrow(existingDF)),]
  existingDF[r,] <- newrow
  existingDF
}

> insertRow(existingDF, newrow, r)
  V1 V2 V3 V4
1  1  6 11 16
2  2  7 12 17
3  1  2  3  4
4  3  8 13 18
5  4  9 14 19
6  5 10 15 20

যদি স্পষ্টতার চেয়ে গতি কম গুরুত্বপূর্ণ হয় তবে @ সাইমন এর সমাধান ভাল কাজ করে:

existingDF <- rbind(existingDF[1:r,],newrow,existingDF[-(1:r),])
> existingDF
   V1 V2 V3 V4
1   1  6 11 16
2   2  7 12 17
3   3  8 13 18
4   1  2  3  4
41  4  9 14 19
5   5 10 15 20

(নোট করুন আমরা rআলাদাভাবে সূচী করি )।

এবং অবশেষে, মানদণ্ড:

library(microbenchmark)
microbenchmark(
  rbind(existingDF[1:r,],newrow,existingDF[-(1:r),]),
  insertRow(existingDF,newrow,r)
)

Unit: microseconds
                                                    expr     min       lq   median       uq       max
1                       insertRow(existingDF, newrow, r) 660.131 678.3675 695.5515 725.2775   928.299
2 rbind(existingDF[1:r, ], newrow, existingDF[-(1:r), ]) 801.161 831.7730 854.6320 881.6560 10641.417

benchmarks

@ ম্যাথডোডোলে সর্বদা আমাকে দেখায় যেহেতু সমস্যার আকার বাড়ার সাথে সাথে স্কেলিংয়ের জন্য বেঞ্চমার্কগুলি পরীক্ষা করা দরকার। এখানে আমরা তারপর যেতে:

benchmarkInsertionSolutions <- function(nrow=5,ncol=4) {
  existingDF <- as.data.frame(matrix(seq(nrow*ncol),nrow=nrow,ncol=ncol))
  r <- 3 # Row to insert into
  newrow <- seq(ncol)
  m <- microbenchmark(
   rbind(existingDF[1:r,],newrow,existingDF[-(1:r),]),
   insertRow(existingDF,newrow,r),
   insertRow2(existingDF,newrow,r)
  )
  # Now return the median times
  mediansBy <- by(m$time,m$expr, FUN=median)
  res <- as.numeric(mediansBy)
  names(res) <- names(mediansBy)
  res
}
nrows <- 5*10^(0:5)
benchmarks <- sapply(nrows,benchmarkInsertionSolutions)
colnames(benchmarks) <- as.character(nrows)
ggplot( melt(benchmarks), aes(x=Var2,y=value,colour=Var1) ) + geom_line() + scale_x_log10() + scale_y_log10()

@ রোল্যান্ডের দ্রবণগুলি খুব ভাল স্কেল করে, এমনকি কল করার জন্যও rbind:

                                                              5       50     500    5000    50000     5e+05
insertRow2(existingDF, newrow, r)                      549861.5 579579.0  789452 2512926 46994560 414790214
insertRow(existingDF, newrow, r)                       895401.0 905318.5 1168201 2603926 39765358 392904851
rbind(existingDF[1:r, ], newrow, existingDF[-(1:r), ]) 787218.0 814979.0 1263886 5591880 63351247 829650894

রৈখিক স্কেলে প্লট করা:

রৈখিক

এবং একটি লগ-লগ স্কেল:

লগ-লগ


3
শেষে একটি সারি োকানো অদ্ভুত আচরণ দেয়!
মার্টেন

@ মার্টেন কোন ফাংশন নিয়ে?
এরি বি ফ্রেডম্যান

আমি অনুমান করি এটির মতোই অদ্ভুত আচরণ আমি এখানে বর্ণনা করছি: stackoverflow.com/questions/19927806/…
প্যাট্রিকটি

1
অদ্ভুত আচরণ আমার নির্দিষ্ট ডেটা ফ্রেম এবং সারিতে ইনসার্টরো 2 দিয়ে ঘটে না।
প্যাট্রিকটি

আপনি কীভাবে একটি ডিএফ-তে সারি সারি সংযুক্ত করবেন? আমার কাছে dfকলাম রয়েছে a,b,c,dএবং আমি সারিটি যুক্ত করতে চাই 1,2,3,4। আমি কেমন করে ঐটি করি?
ট্র্যাভিস হিটার

44
insertRow2 <- function(existingDF, newrow, r) {
  existingDF <- rbind(existingDF,newrow)
  existingDF <- existingDF[order(c(1:(nrow(existingDF)-1),r-0.5)),]
  row.names(existingDF) <- 1:nrow(existingDF)
  return(existingDF)  
}

insertRow2(existingDF,newrow,r)

  V1 V2 V3 V4
1  1  6 11 16
2  2  7 12 17
3  1  2  3  4
4  3  8 13 18
5  4  9 14 19
6  5 10 15 20

microbenchmark(
+   rbind(existingDF[1:r,],newrow,existingDF[-(1:r),]),
+   insertRow(existingDF,newrow,r),
+   insertRow2(existingDF,newrow,r)
+ )
Unit: microseconds
                                                    expr     min       lq   median       uq      max
1                       insertRow(existingDF, newrow, r) 513.157 525.6730 531.8715 544.4575 1409.553
2                      insertRow2(existingDF, newrow, r) 430.664 443.9010 450.0570 461.3415  499.988
3 rbind(existingDF[1:r, ], newrow, existingDF[-(1:r), ]) 606.822 625.2485 633.3710 653.1500 1489.216

3
এটি একটি দুর্দান্ত সমাধান। এটি কেন একই সাথে আহ্বানের চেয়ে এত দ্রুততর তা বুঝতে পারি না rbind, তবে আমি আগ্রহী।
এরি বি ফ্রেডম্যান

মাপদণ্ডের সাথে উত্তরগুলির স্বয়ংক্রিয়ভাবে আইএমও প্রয়োগ করা উচিত extra ধন্যবাদ!
অ্যালেক্স

10

আপনার dplyr প্যাকেজ চেষ্টা করা উচিত

library(dplyr)
a <- data.frame(A = c(1, 2, 3, 4),
               B = c(11, 12, 13, 14))


system.time({
for (i in 50:1000) {
    b <- data.frame(A = i, B = i * i)
    a <- bind_rows(a, b)
}

})

আউটপুট

   user  system elapsed 
   0.25    0.00    0.25

Rbind ফাংশন ব্যবহারের বিপরীতে

a <- data.frame(A = c(1, 2, 3, 4),
                B = c(11, 12, 13, 14))


system.time({
    for (i in 50:1000) {
        b <- data.frame(A = i, B = i * i)
        a <- rbind(a, b)
    }

})

আউটপুট

   user  system elapsed 
   0.49    0.00    0.49 

কিছু পারফরম্যান্স লাভ আছে।


-4

উদাহরণস্বরূপ, আপনি "প্রান্ত" নামের একটি ডেটা ভেরিয়েবল 1-এ ভেরিয়েবল 2 এর সারি যুক্ত করতে চান ঠিক এটি এটি করুন

allEdges <- data.frame(c(edges$V1,edges$V2))
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.