rânduri duplicate într-un cadru de date în R (Programare, R, Dataframe)

tubby a intrebat.

Încerc să dublez rândurile din cadrul meu de date folosind codul de mai jos.Cu toate acestea, mi se pare că este lent.

duprow = df[1,]
for(i in 1:2000)
{
    print(i)
    df = rbind(df,duprow)
}

Există o modalitate mai rapidă?

5 răspunsuri
lukeA

Puteți utiliza rep, , de exemplu, pentru 5 duplicate sau rândul 1:

df <- data.frame(x = 1, y = 1)
rbind(df, df[rep(1, 5), ])
#     x y
# 1   1 1
# 11  1 1
# 1.1 1 1
# 1.2 1 1
# 1.3 1 1
# 1.4 1 1

Andrew

Iată ce am încercat eu să fac:

> # create an example data frame
> colornames=c("violet","indigo","blue","green","yellow","orange","red")
> wavelength=c(400,425,470,550,600,630,665)
> df <- data.frame(colornames, wavelength)
> 
> # How many replicates you want of each row
> duptimes <- c(0,1,2,1,1,4,1)
> 
> # Create an index of the rows you want with duplications
> idx <- rep(1:nrow(df), duptimes)
> 
> # Use that index to genderate your new data frame
> dupdf <- df[idx,]
> 
> # display results
> df
  colornames wavelength
1     violet        400
2     indigo        425
3       blue        470
4      green        550
5     yellow        600
6     orange        630
7        red        665
> dupdf
    colornames wavelength
2       indigo        425
3         blue        470
3.1       blue        470
4        green        550
5       yellow        600
6       orange        630
6.1     orange        630
6.2     orange        630
6.3     orange        630
7          red        665

Nu știu dacă este mai rapid, dar nu necesită încărcarea unor pachete suplimentare și, de asemenea, elimină rândurile nedorite.

Dezavantajul este că trebuie să luați decizii cu privire la fiecare rând din cadrul de date, dar asta nu ar trebui să fie prea dificil de codificat.

Comentarii

  • Acest lucru a funcționat bine pentru mine și a fost rapid folosind un cadru de date care a început cu 1 milion de rânduri. Dacă doriți să efectuați același număr de repetări pentru fiecare rând, puteți utiliza reptimes <- 12; idx <- rep(1:nrow(df), reptimes); rep_df <- df[idx, ] –  > Por mikey.
  • Acest truc este ingenios. Funcționează și pentru vectori și îl puteți aplica de mai multe ori pentru a cuibări date. –  > Por piegames.
Maarten

Am avut o problemă similară ieri și există, de asemenea, acest pachet numit „splitstackshape”. Apoi, este la fel de simplu ca și următorul cod:

library(splitstackshape)
df <- data.frame(x = 1, y = 1)
df2 <- expandRows(df, count=2000, count.is.col=FALSE)

S-ar putea, de asemenea, să doriți să „reparați” rownames făcând

rownames(df2) <- 1:2000

Comentarii

  • De obicei, eu folosesc doar rownames(df2) <- NULL pentru a obține același efect. Sau, dacă intrarea este un data.table, , nu vor exista nume de rânduri pentru început. De ex: expandRows(as.data.table(df), count = 2000, count.is.col = FALSE) –  > Por A5C1D2H2H2I1M1N2O1R2T1.
micstr

Răspunsul lui Luke folosind rep() îți face treaba pentru moment, dar aceste răspunsuri de mai jos ar putea să te ajute pe termen lung.

  1. Vă rugăm să aruncați o privire la acest răspuns pe accelerarea rbind despre motivele pentru care este lent și să nu folosiți bucle. De asemenea, are un cod pentru a prealoca cadrul de date. De asemenea, consultați comentariul lui Jorans al doilea cerc al iadului.

  2. Sugestie rbind.fill De la @coanil

    Două lucruri pe care aș dori să le adaug: 1) În general, dacă nu doriți să folosiți data.table, puteți folosi funcția rbind.fill din pachetul plyr al lui Hadley, care este și destul de rapidă. Nu folosiți niciodată rbind așa cum ați făcut-o mai sus, într-o buclă „for”, adăugând fiecare rând separat. Aceasta forțează R să facă o copie a obiectului cadru de date de fiecare dată când adăugați un rând, iar acest lucru este lent.

https://stackoverflow.com/a/19699342/4606130

  1. Dacă folosiți data.table utilizați rbindlist care este mai rapid. (@David sugerează acest lucru în primul link de răspuns).

Adriaan Nering Bögel

Am avut o problemă similară pe care am vrut să o rezolv într-un mod ordonat folosind dplyr. Am ajuns să filtrez rândurile desemnate din dataframe-ul meu pe baza rownumber folosind dplyr::filter() și dplyr::row_number(). Și legându-le la dataframe-ul original folosind dplyr::bind_rows(), , toate într-o singură țeavă. În exemplul dvs. ar fi ceva de genul următor:

df %>% 
  filter(row_number() <= 2000) %>% 
  bind_rows(df)

Rapid și ușor dacă doriți să duplicați anumite rânduri! Bineînțeles că puteți folosi numere de rânduri specifice pentru a le duplica, folosind filter(row_number() %in% c(...)).

Tags:,