[TIL] 250210 R libraries

MONA·2025년 2월 10일

나혼공

목록 보기
55/92

reshape2

R에서 데이터를 변환하는 데 사용되는 패키지

melt()
데이터를 long format으로 변환
데이터의 열을 하나의 열로 노력서 변환하는 데 사용됨

library(reshape2)

df <- data.frame(
  id = c(1, 2, 3),
  math = c(90, 80, 70),
  english = c(85, 75, 95)
)
df
  id math english
1  1   90      85
2  2   80      75
3  3   70      95
df_long <- melt(df, id.vars = "id")
df_long
  id variable value
1  1     math    90
2  2     math    80
3  3     math    70
4  1  english    85
5  2  english    75
6  3  english    95
  • id.vars = 'id'; id를 고정된 기준 열로 유지
  • math, english 열이 variable 열로 melt됨
  • 각 성적이 value에 저장됨

dcast()
long format을 다시 wide format으로 변환

df_wide <- dcast(df_long, id ~ variable)
df_wide
  id math english
1  1   90      85
2  2   80      75
3  3   70      95
  • id ~ variable: id를 기준으로 각 variable의 값(value)을 열로 확장

acast()
결과를 벡터, 행렬(matrix) 또는 배열(array) 형식으로 변환

df_matrix <- acast(df_long, id ~ variable)
df_matrix
     math english
1    90      85
2    80      75
3    70      95
  • acast(): 배열 또는 행렬 형태로 데이터를 변환
  • dcast()와 같은 방식으로 동작하지만, 행렬 연산에 적합한 형태로 데이터를 출력함

여러 기준으로 데이터 포맷 변환

score <- data.frame(
  student_number = c(1, 2, 1, 2), 
  semester = c(1,1,2,2), 
  math_score = c(60, 90, 70, 90), 
  english_score = c(80, 70, 40, 60))
  
melt(score, id = c("student_number", "semester"))
  student_number semester      variable value
1              1        1    math_score    60
2              2        1    math_score    90
3              1        2    math_score    70
4              2        2    math_score    90
5              1        1 english_score    80
6              2        1 english_score    70
7              1        2 english_score    40
8              2        2 english_score    60

sqldf

R에서 data frame을 대상으로 SQL query를 실행할 수 있도록 돕는 라이브러리.
data frame을 database처럼 다룰 수 있다.

  • SQL 문법을 사용해 data frame을 조작할 수 있음
  • 기본적으로 SQLite를 백엔드로 사용
    -subset(), aggregate(), merge() 등의 R 함수를 대체할 수 있음
  • 복잡한 필터링과 Join 연산을 SQL 문법으로 간편하게 처리 가능
install.packages("sqldf")
install.packages("gsubfn")
install.packages("proto")
install.packages("RSQLite")
library(sqldf)

sqldf('select * from score')
sqldf('select * from score where student_number = 1')
sqldf('select avg(math_score), avg(english_score) from score group by student_number')
df <- data.frame(
  id = c(1, 2, 3, 4, 5),
  name = c("kim", "lee", "park", "choi", "jeong"),
  age = c(25, 30, 35, 40, 22),
  score = c(90, 85, 88, 92, 78)
)

df2 <- data.frame(
  id = c(1, 2, 3, 4, 5),
  city = c("Seoul", "Busan", "Incheon", "Daegu", "Gwangju")
)

sqldf("SELECT df.id, df.name, df.score, df2.city FROM df INNER JOIN df2 ON df.id = df2.id")
  id  name score    city
1  1   kim    90   Seoul
2  2   lee    85   Busan
3  3  park    88 Incheon
4  4  choi    92   Daegu
5  5 jeong    78 Gwangju

SQL query에서 data frame의 이름을 그대로 테이블명처럼 사용할 수 있음
SQL query는 대소문자를 구분하지 않지만 컬럼명은 대소문자를 구분할 수 있음

sqldf에서는 ALTER TABLE을 직접 사용할 수 없기 때문에 SELECT를 활용해 새로운 컬럼을 추가 가능

sqldf("SELECT *, score * 1.1 AS adjusted_score FROM df")
  id  name age score adjusted_score
1  1   kim  25    90           99.0
2  2   lee  30    85           93.5
3  3  park  35    88           96.8
4  4  choi  40    92          101.2
5  5 jeong  22    78           85.8
  • sqldf: sql 문법을 사용하여 직관적으로 데이터를 다룰 수 있음
  • R 기본 함수는 벡터 기반 연산을 사용하지만, sqldf는 sql 스타일로 작업을 수행함

plyr

R에서 데이터 프레임(data.frame), 리스트(list), 배열(array) 등의 데이터를 그룹화하고 변환하는 기능을 제공하는 라이브러리.

주요 함수 패턴

(입력 데이터 유형) + (출력 데이터 유형) + "ply"
함수입력출력설명
ddply()data.framedata.framedata frame을 그룹화하여 처리
dlply()data.framelistdata frame을 list로 변환
ldply()listdata.framelist를 data frame으로 변환
llply()listlistlist 변환

ddply()

기본 문법

ddply(.data, .variables, .fun, ...)

.data: data frame
.variables: 그룹화할 기준이 되는 변수(문자형 또는 벡터. 복수 가능)
.fun: 적용할 함수
...: 추가 매개변수

install.packages("plyr")
library(plyr)

score2 <- data.frame(
  class = c('A', 'A', 'B', 'B'), 
  math = c(50, 70, 60, 90), 
  english = c(70, 80, 60, 80))

summarise(): 그룹별로 요약(집계)된 데이터를 생성하는 함수

ddply(score2, "class", summarise, math_avg = mean(math), eng_avg = mean(english))
  • score2를 class별로 그룹화
  • 각 그룹에 대해 math와 english의 평균값을 계산
  • 결과는 그룹별 평균값을 포함한 새로운 data frame으로 반환
  class math_avg eng_avg
1     A       60      75
2     B       75      70

transform(): 기존 data frame에 새로운 컬럼 추가.

ddply(score2, "class", transform, math_avg = mean(math), eng_avg = mean(english))
  • score2를 class별로 그룹화
  • math_avg와 eng_avg라는 새로운 열을 추가해 그룹별 평균값 저장
  • 기존 데이터프레임의 행 개수를 유지한 상태에서 값이 추가됨
  class math english math_avg eng_avg
1     A   50      70       60      75
2     A   70      80       60      75
3     B   60      60       75      70
4     B   90      80       75      70

여러 개의 변수를 기준으로 그룹을 지정할수도 있음

ddply(data, c("year", "month"), summarise, value_avg = mean(value))
  • data를 year와 month 기준으로 그룹화
  • value 컬럼의 평균값을 계산하여 value_avg라는 새로운 열로 저장
  • year와 month의 조합별 평균값이 포함된 데이터프레임 반환
  year month value_avg
1 2012     1       4.0
2 2012     2       7.5
3 2013     1       3.0
4 2013     2       5.0

사용자 정의 함수를 적용할 수도 있다

ddply(data, c("year", "month"), function(x) {
  value_avg = mean(x$value)
  value_sd = sd(x$value)
  data.frame(avg_ad = value_avg / value_sd)
})
  • year와 month 별로 데이터를 그룹화
  • 각 그룹에서 value의 평균과 표준편차를 계산
  • avg_ad = 평균 / 표준편차 값을 계산하여 새로운 데이터프레임 반환
  year month   avg_ad
1 2012     1 2.828427
2 2012     2 6.0
3 2013     1 2.121320
4 2013     2 5.0

data.table

R에서 대용량 데이터 처리를 빠르고 효율적으로 수행할 수 있도록 설계된 데이터프레임(data.frame) 확장형 패키지.
빠른 속도와 간결한 문법 지원

install.packages("data.table")
library(data.table)

year <- rep( c(2012:2015), each = 12000000 ) # 연도별 1200만개 행 데이터 생성
month <- rep( rep( c(1:12), each = 1000000), 4) # 월별 100만개 행 데이터 생성
value <- runif( 48000000 ) # 0~1사이의 랜덤값 배정

DF <- data.frame(year, month, value) # 기본 data.frame
DT <- as.data.table( DF ) # data.table 변환
# DF$year == 2012 조건을 만족하는 행을 찾아 반환
system.time( DF[ DF$year == 2012, ]) 
system.time( DT[ DT$year == 2012, ])
setkey( DT, year )
system.time(DT[J(2012)])
> system.time( DF[ DF$year == 2012, ])
   user  system elapsed 
  0.454   0.058   0.512 
> system.time( DT[ DT$year == 2012, ])
   user  system elapsed 
  0.108   0.029   0.104
> setkey( DT, year )
> system.time(DT[J(2012)])
   user  system elapsed 
  0.136   0.018   0.060 
  • 기본 data.frame 필터링(DT): 선형 탐색(O(n)) 수행
  • data.table 필터링(DF): DF보다는 빠르지만 여전히 전체 데이터 탐색을 수행함
  • setkey()로 year에 키 설정한 후 탐색: 데이터가 정렬되면서 이진 탐색(O(logn)) 가능
    • J(2012)(키 기반 조회) 사용으로 즉시 해당 행을 찾아서 반환(hash lookup)
profile
고민고민고민

0개의 댓글