data.frame의 각 행을 반복합니다. 열에 지정된 횟수
df <- data.frame(var1 = c('a', 'b', 'c'), var2 = c('d', 'e', 'f'),
freq = 1:3)
각 행을 위의 data.frame의 처음 두 열로 확장하여 각 행이 'freq' 열에 지정된 횟수만큼 반복되도록 하는 가장 간단한 방법은 무엇입니까?
다시 말해, 다음과 같습니다.
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
한 가지 해결책이 있습니다.
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
오래된 질문, 깔끔한 역의 새로운 동사:
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
사용하다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
@tftfws의 솔루션은 다음과 같은 환경에 적합합니다.data.frame
s, 하지만 이 아닌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"]
다른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)
그렇지 않다는 것은 알지만 원래의 freq 열을 유지해야 한다면 다른 열을 사용할 수 있습니다.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
reprex 패키지(v0.3.0)에 의해 2019-12-21에 생성되었습니다.
매우 큰 data.frames에서 이 작업을 수행해야 하는 경우에는 data.table로 변환하여 훨씬 더 빨리 실행되는 다음을 사용하는 것이 좋습니다.
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
다른 가능성은 다음과 같습니다.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
vonjd의 답변의 한 줄 버전:
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
reprex 패키지(v0.2.1)에 의해 2019-05-21에 생성되었습니다.
이 멋진 답변에 한 가지를 더 추가해 드립니다!사용tidyr
패키지(에 포함)tidyverse
) 한 줄 솔루션의 경우:
df %>% tidyr::uncount(weights = freq)
실은.벡터와 인덱스의 방법을 사용합니다. 또한 동일한 결과를 얻을 수 있으며, 더 쉽게 이해할 수 있습니다.
rawdata <- data.frame('time' = 1:3,
'x1' = 4:6,
'x2' = 7:9,
'x3' = 10:12)
rawdata[rep(1, time=2), ] %>% remove_rownames()
# time x1 x2 x3
# 1 1 4 7 10
# 2 1 4 7 10
언급URL : https://stackoverflow.com/questions/2894775/repeat-each-row-of-data-frame-the-number-of-times-specified-in-a-column
'programing' 카테고리의 다른 글
FirebaseRemoteConfig 오류 "파라미터 키에 대해 'String' 유형의 값이 없습니다." (0) | 2023.06.11 |
---|---|
WebAPI에서 POST 데이터를 가져오는 방법은 무엇입니까? (0) | 2023.06.11 |
C Make로 C 수학 라이브러리에 링크하는 방법은 무엇입니까? (0) | 2023.06.11 |
Excel 매크로 - 데이터와 형식을 표로 사용하는 모든 셀 선택 (0) | 2023.06.11 |
Android에서 SQLite를 사용할 때 동시성 문제를 방지하려면 어떻게 해야 합니까? (0) | 2023.06.11 |