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
패키지 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
오래된 질문, tidyverse의 새로운 동사 :
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
@neilfws의 솔루션은 data.frame
s에는 훌륭하게 작동 하지만 속성이 data.table
없기 때문에 s 에는 적합하지 않습니다 row.names
. 이 방법은 두 가지 모두에 적용됩니다.
df.expanded <- df[rep(seq(nrow(df)), df$freq), 1:2]
의 코드 data.table
는 tad cleaner입니다.
# convert to data.table by reference
setDT(df)
df.expanded <- df[rep(seq(.N), freq), !"freq"]
In case you have to do this operation on very large data.frames I would recommend converting it into a data.table and use the following, which should run much faster:
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
See how much faster this solution is:
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
Another dplyr
alternative with slice
where we repeat each row number freq
times
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())
part can be replaced with any of the following.
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)
Another possibility is using 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
One-liner version of vonjd's answer:
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
Created on 2019-05-21 by the reprex package (v0.2.1)
'Programming' 카테고리의 다른 글
크롬은 "이 페이지가 추가 대화 상자를 만드는 것을 방지"의 작업을 취소합니다. (0) | 2020.07.12 |
---|---|
jQuery를 사용하여 포인터를 손가락으로 바꾸는 방법은 무엇입니까? (0) | 2020.07.12 |
순간에 기간 추가 (moment.js) (0) | 2020.07.12 |
다른 스레드가 완료되었는지 확인하는 방법은 무엇입니까? (0) | 2020.07.12 |
공유 객체에서 모든 심볼을 내보내는 방법은 무엇입니까? (0) | 2020.07.12 |