itsource

data.frame 행을 반복합니다.

mycopycode 2023. 6. 6. 08:20
반응형

data.frame 행을 반복합니다.

각각 data.frame 행을 반복합니다.N시간. 결과는 새로운 것이어야 합니다.data.frame(와 함께)nrow(new.df) == nrow(old.df) * N열의 데이터 형식을 유지합니다.

N = 2의 예:

                        A B   C
  A B   C             1 j i 100
1 j i 100     -->     2 j i 100
2 K P 101             3 K P 101
                      4 K P 101

따라서 각 행은 두 번 반복되고 문자는 문자로 유지되고 요인은 요인으로 유지되며 숫자는 숫자로 유지됩니다.

처음 사용한 시도는 다음과 같습니다.apply(old.df, 2, function(co) rep(co, each = N))하지만 이것은 제 가치를 캐릭터로 바꾸고, 저는 다음과 같은 것을 얻습니다.

     A   B   C    
[1,] "j" "i" "100"
[2,] "j" "i" "100"
[3,] "K" "P" "101"
[4,] "K" "P" "101"
df <- data.frame(a = 1:2, b = letters[1:2]) 
df[rep(seq_len(nrow(df)), each = 2), ]

깨끗한dplyr솔루션, 여기서 가져옵니다.

library(dplyr)
df <- tibble(x = 1:2, y = c("a", "b"))
df %>% slice(rep(1:n(), each = 2))

특정 행만 각각 n번 반복하는 사랑스러운 벡터화 솔루션이 있습니다. 예를 들어, 다음과 같은 방법을 추가하면 가능합니다.ntimes데이터 프레임 열:

  A B   C ntimes
1 j i 100      2
2 K P 101      4
3 Z Z 102      1

방법:

df <- data.frame(A=c("j","K","Z"), B=c("i","P","Z"), C=c(100,101,102), ntimes=c(2,4,1))
df <- as.data.frame(lapply(df, rep, df$ntimes))

결과:

  A B   C ntimes
1 Z Z 102      1
2 j i 100      2
3 j i 100      2
4 K P 101      4
5 K P 101      4
6 K P 101      4
7 K P 101      4

이것은 Josh O'Brien과 Mark Miller의 방법과 매우 유사합니다.

df[rep(seq_len(nrow(df)), df$ntimes),]

그러나 이 방법은 상당히 느리게 나타납니다.

df <- data.frame(A=c("j","K","Z"), B=c("i","P","Z"), C=c(100,101,102), ntimes=c(2000,3000,4000))

microbenchmark::microbenchmark(
  df[rep(seq_len(nrow(df)), df$ntimes),],
  as.data.frame(lapply(df, rep, df$ntimes)),
  times = 10
)

결과:

Unit: microseconds
                                      expr      min       lq      mean   median       uq      max neval
   df[rep(seq_len(nrow(df)), df$ntimes), ] 3563.113 3586.873 3683.7790 3613.702 3657.063 4326.757    10
 as.data.frame(lapply(df, rep, df$ntimes))  625.552  654.638  676.4067  668.094  681.929  799.893    10

전체를 반복할 수 있거나 먼저 부분 집합을 지정한 후 반복할 수 있다면 이와 유사한 질문이 도움이 될 수 있습니다.다시 한 번:

library(mefa)
rep(mtcars,10) 

아니면 간단히

mefa:::rep.data.frame(mtcars)

@dardisc에서 언급한 내용에 추가mefa::rep.data.frame()신축성이 아주 좋습니다.

각 행을 N회 반복할 수 있습니다.

rep(df, each=N)

또는 전체 데이터 프레임을 N번 반복합니다(예: 벡터화된 인수를 재활용할 때).

rep(df, times=N)

두 엄지손가락을 치켜세워라.mefa나는 지금까지 그것에 대해 들어본 적이 없었고 이것을 하기 위해 수동 코드를 작성해야 했습니다.

메파를 인용한 답변을 참조하고 추가하기 위해, 구현을 검토할 가치가 있을 수 있습니다.mefa::rep.data.frame()전체 패키지를 포함하지 않으려는 경우:

> data <- data.frame(a=letters[1:3], b=letters[4:6])
> data
  a b
1 a d
2 b e
3 c f
> as.data.frame(lapply(data, rep, 2))
  a b
1 a d
2 b e
3 c f
4 a d
5 b e
6 c f

rep.row 함수는 때때로 열에 대한 목록을 만드는 것처럼 보이며, 이는 잘못된 메모리 히딩크로 이어집니다.저는 다음과 같이 잘 작동하는 것처럼 보이는 글을 썼습니다.

library(plyr)
rep.row <- function(r, n){
  colwise(function(x) rep(x, n))(r)
}

다음과 유사한 내 솔루션mefa:::rep.data.frame하지만 조금 더 빠르고 행 이름에 신경을 씁니다.

rep.data.frame <- function(x, times) {
    rnames <- attr(x, "row.names")
    x <- lapply(x, rep.int, times = times)
    class(x) <- "data.frame"
    if (!is.numeric(rnames))
        attr(x, "row.names") <- make.unique(rep.int(rnames, times))
    else
        attr(x, "row.names") <- .set_row_names(length(rnames) * times)
    x
}

솔루션 비교:

library(Lahman)
library(microbenchmark)
microbenchmark(
    mefa:::rep.data.frame(Batting, 10),
    rep.data.frame(Batting, 10),
    Batting[rep.int(seq_len(nrow(Batting)), 10), ],
    times = 10
)
#> Unit: milliseconds
#>                                            expr       min       lq     mean   median        uq       max neval cld
#>              mefa:::rep.data.frame(Batting, 10) 127.77786 135.3480 198.0240 148.1749  278.1066  356.3210    10  a 
#>                     rep.data.frame(Batting, 10)  79.70335  82.8165 134.0974  87.2587  191.1713  307.4567    10  a 
#>  Batting[rep.int(seq_len(nrow(Batting)), 10), ] 895.73750 922.7059 981.8891 956.3463 1018.2411 1127.3927    10   b

예를 들어 사용해 보십시오.

N=2
rep(1:4, each = N) 

색인으로서

다른 방법으로는 먼저 행 인덱스를 가져오고 df 복사본을 추가한 다음 인덱스를 기준으로 정렬하는 것이 있습니다.

df$index = 1:nrow(df)
df = rbind(df,df)
df = df[order(df$index),][,-ncol(df)]

다른 솔루션은 더 짧을 수 있지만 특정 상황에서는 이 방법이 더 유리할 수 있습니다.

언급URL : https://stackoverflow.com/questions/11121385/repeat-rows-of-a-data-frame

반응형