Tools (135)

반응형

 

아래 코드는 일별로 유저수와 그 유저의 피쳐 a,b,c 에 대해 각각 평균과 중위수를 구하는 코드이다. 이 코드는 상당히 시간이 오래 걸린다.

select 
date_id,
count(distinct user_id) as user_cnt,
avg(a) as avg_a,
avg(b) as avg_b,
avg(c) as avg_c,
percentile_approx(a, 0.5) as med_a,
percentile_approx(b, 0.5) as med_b,
percentile_approx(c, 0.5) as med_b
from table
group by date_id

 

그런데, user_cnt 와 평균을 구하는 코드를 제외한 아래 쿼리는 빠르게 실행된다. 왜 그럴까?

select 
date_id,
percentile_approx(a, 0.5) as med_a,
percentile_approx(b, 0.5) as med_b,
percentile_approx(c, 0.5) as med_b
from table
group by date_id

 

챗 GPT 를 활용해 답변을 생성해보니 아래와 같다고 한다.

 

유저수를 count하는 연산과 평균을 구하는 연산이 맵리듀스 분산 처리시(Big Data 환경을 가정) 각 노드에서 개별적으로 이루어져서 빠른 처리가 가능하지만, 중앙값을 구하는 percentile_approx 연산은 전체 데이터를 한 노드에서 모아서 처리해야 하기 때문에 상대적으로 시간이 많이 소요됩니다.

하지만, 여러 컬럼의 중앙값을 동시에 구하는 쿼리에서는 중앙값을 구하는 작업이 모든 컬럼에 대해 동시에 이루어지기 때문에 시간이 대폭 줄어듭니다.

즉, count와 avg는 분산처리가 가능하여 각각의 연산이 독립적이지만 percentile_approx는 분산처리가 어려워서 전체 데이터에 대한 연산이 필요하여 시간이 오래 걸린 것입니다. 두번째 쿼리는 percentile_approx만 있기 때문에 동시에 처리될 수 있어 속도가 빠른 것입니다.

확인하기 위해, 각각의 연산을 따로 실행하는 쿼리를 만들어 시간을 체크해보면 더 정확한 비교가 가능할 것입니다.

 

결론

- hive sql 에서 percentile_approx 는 분산처리가 어렵고 전체 데이터에 대한 연산이 필요하기 때문에 시간이 오래 걸린다. 

- hive sql 에서 percentile_approx 를 활용해 중위수를 구할 때에는 다른 집계는 하지 말고 중위수만 구하자. 그럼 조금 더 빠르다. 

반응형

'Tools > SQL' 카테고리의 다른 글

여러 테이블을 Full outer join 하기  (0) 2022.08.25
반응형

R studio server 에서 knitr 에러 발생시 해결 방법

아래와 같은 오류 또는 test_env 를 찾을 수 없습니다. 등, Rmd 파일을 knitr 을 통해 변환시킬 때 에러가 발생했다. 

 

에러 메시지 예시

  |................................                                 |  50%
  ordinary text without R code

  |.................................................................| 100%


processing file: Preview-b0c112a265.Rmd
label: unnamed-chunk-1

Quitting from lines 16-26 (Preview-b0c112a265.Rmd) 
Error in file(file, "rt") : cannot open the connection
Calls: <Anonymous> ... withVisible -> eval -> eval -> read.csv -> read.table -> file
Execution halted

 

해결: [Tool] - [Global Options] - [R Markdown] - Evaluate Chunks in Directory 를 current 로 변경

 

위와 같이 세팅을 변경하자 문제가 해결되었다. 위 문제로 인해 마크다운 문서를 작성할 때 Rstudio server 가 아니라 로컬에서 작업을 항상 했었는데 불편함이 존재했었다. 위 방법으로 깔끔하게 해결되었고, 앞으로 마크다운 문서 작성도 R studio server 에서 하면 될듯하다.

 

참고 : https://stackoverflow.com/questions/26994958/error-cannot-open-the-connection-in-executing-knit-html-in-rstudio

반응형
반응형

R - Distill + github pages 로 간단한 블로그 만들기

 

R markdown 형식을 html 로 변환해 호스팅하는 패키지로 blogdown 이 유명했는데 최근 많은 유저들이 distill 로 많이 갈아타고 있는듯하다. blogdown 의 경우 hugo 를 기본으로 블로그 템플릿이 만들어지는데 hugo 보다 distill 의 기본 포맷이 조금 더 학술적인 느낌이기 때문에 개인적으로 distill 이 R 관련 포스팅에 좀 더 적합한 느낌으로 보인다. 

 

Distill Manual : https://rstudio.github.io/distill/blog.html

The Distillery: Distill 매뉴얼은 조금 드라이하게 작성 되어 있는듯하다. distill 사용을 좀 더 잘하기 위한 tip 등을 공유하는 사이트로 The Distillery 가 있다. (https://distillery.rbind.io/tips_and_tricks) 여기에서는 Distill 을 사용할 때의 tips and tricksshowcase 를 공유한다. showcase 를 보면 다른 유저들이 distill 을 이용해서 블로그를 어떻게 운영하고 있는지를 볼 수 있어 개인 블로그를 만드는데 참고가 될 것이다. 

 

간단하게 Distill 과 Github pages 를 통해 10분 이내로 블로그를 만들어보자.

물론 github 계정, git 설치, R 설치는 기본적으로 필요하다.

 

Distill 설치

install.packages('distill')

 

Distill Blog Project 생성

 

위와 같이 블로그를 생성하면 홈폴더 바로 아래에 있는 하위 폴더에 "_site" 라는 폴더가 있는데 여기에 웹사이트 최초 시작지점인 index.html 파일이 존재한다. 이렇게 github pages 로 push 하면 [githubID].github.io/_site 가 블로그의 주소가 된다. 만약 [githubId].github.io 를 주소로 블로그를 호스팅하고 싶다면, _site 에 위치한 파일들을 모두 home 폴더로 옮겨준다. 그리고 홈폴더 바로 아래에 있는 _site.yaml 파일의 output_dir 을 "." 으로 설정한다. 

 

_site.yaml 파일은 다음과 같이 될 것이다. 

name: "[id].github.io"
title: "My Blog"
description: |
  My Blog
output_dir: "."
navbar:
  right:
    - text: "Home"
      href: index.html
    - text: "About"
      href: about.html
output: distill::distill_article
collections:
  posts:
    categories: true
    categories_metadata: true
    authors_metadata: true

 

본인의 github 에 [id].github.io 라는 이름의 레포지토리를  만들고 여기에 만든 코드를 push 를 해주면 블로그가 잘 생성된 것을 볼 수 있다. github pages 로 푸시하는 과정은 아래와 같다.  

cd [home] # 생성한 distill 프로젝트의 홈폴더로 이동한다. 
git init
git add --all
git commit -m 'first commit'
git remote add origin https://github.com/[id]/[id].github.io
git push origin master

 

아래와 같은 형태의 기본 Distill 템플릿의 블로그가 생성되었다.

 

 

* 또는 output_dir 을 docs 로 설정한 후, github pages 설정에서 source 폴더를 docs 폴더로 설정하는 것을 추천한다.

 

 

포스트 조금 수정해보기

 

1) 포스트에 카테고리 붙이기

기본적인 블로그에는 오른쪽의 CATEGORIES 메뉴가 없을 것이다. 카테고리를 만드는 방법은 단순히 포스트에 다가 category tag 를 붙이면된다. 카테고리를 직접적으로 지정할 필요없이 포스트에 붙어 있는 태그를 통해 전체 카테고리가 재구성된다. 

---
title: "Welcome to My Blog"
categories:
- Category1
- Category2
- Category3
description: |
  Welcome to our new blog, My Blog. We hope you enjoy 
  reading what we have to say!
author:
  - name: Nora Jones 
    url: https://example.com/norajones
    affiliation: Spacely Sprockets
    affiliation_url: https://example.com/spacelysprokets
date: 08-23-2024
output:
  distill::distill_article:
    self_contained: false
---

 

2) rmd 를 html 형식으로 변환하기

- 카테고리를 붙이는 등 rmd 파일을 수정했다면 이를 html 로 변환해줄 필요가 있다. 

- 기본적으로 rstudio 에서 build - Install and Restart 를 누르면 빌드된다. 

- 다만 build 를 통해서는 각 포스트가 html 로 변환되지는 않는다. 포스트를 변환하기 위해서는 각 rmd 파일에 대해 knitr 을 실행해서 rmd 파일을 html 파일로 변환해주면 된다. 

Knit 를 통해 rmd 파일을 html 파일로 변환함으로써 github pages 를 통해 호스팅할 수 있다. 

반응형
반응형

R - ggplot 의 유용한 add-on 패키지 ggrepel

 

R 에서 ggplot 을 통해 그래프를 그릴 때 불편했던 점이 텍스트 레이블을 차트에 표시하기 어려웠던 점이다. 엑셀로 그래프를 그리는 경우 레이블 옵션을 설정한 뒤 이를 마우스 드래그를 통해서 조정할 수 있으나, ggplot 에서는 hjust, vjust 를 통해 한땀한땀 레이블을 조정하곤했다. 

 

혹시나 레이블의 위치를 자동으로 바꿔주는 패키지가 있나 살펴보다가 ggrepel 이라는 패키지가 있다는 것을 알았다. 사용법은 매우 쉽다. 만드려고한 ggplot 에다가 +  geom_text_repel() 만 해주면 된다. 

 

 

 

텍스트간의 겹치는 것을 조정해주기도 하지만, line 이나 point 와 같은 그래프의 요소와 텍스트가 겹치는 것을 알아서 조정해주기도 한다. 아래의 line chart 를 보면 point 와 겹치지 않게 text 가 자동으로 위치가 조정된 것을 볼 수 있다. 

ggplot(aes(x=x, y=y, group=g, label=round(t,2)), data=data) +
  geom_line(aes(color=g), size=1) +
  geom_point(aes(color=g)) + 
  theme_bw(base_size=10, base_family = "Kakao Regular") +
  theme(strip.background =element_rect(fill="#DEEBFF"),
        strip.text.x = element_text(size = 10),
        legend.position="right", 
        plot.title = element_text(hjust = 0.5, size=12), 
        axis.text.x = element_text(size=10),
        legend.text=element_text(size=10),
        legend.title=element_text(size=15),
        panel.grid.minor = element_line(size = 1), 
        panel.grid.major = element_line(size = 1),
        plot.background = element_rect(colour = "#cdcdcd",size = 0.5)) +
  ggtitle("Plot Title") +
  labs(color = 'STRATA') +
  ylab("Y LAB") + xlab("X LAB")+
  geom_text_repel()

 

반응형
반응형

 

 

 

quantile_output 이라는 폴더 아래에 6월 1일~6월 30일 사이의 30개의 csv 파일이 존재한다. 각 파일들은 같은 형식이며, 각기 다른 날짜에 집계됐다는 점만 다르다. 이 경우에 1) Sys.glob 을 이용해 해당 파일들의 경로를 벡터 형태로 만든 후에 2) lapply 를 통해 각 파일들을 읽어 list of dataframes 를 만들고, 3) 마지막으로 bind_rows 를 통해 dataframe 으로 만들어주면 된다.  

result_files <- Sys.glob("quantile_output/quantile_2024-06*")
result_list <- lapply(result_files, function(x) read_csv(x))
merged <- dplyr::bind_rows(result_list)

 

반응형
반응형

R 로 벤다이어그램을 그려보자 VennDiagram 패키지

 

어떠한 두 그룹의 교차되는 부분의 규모를 표현할 때, 벤다이어그램은 매우 효과적인 방법입니다. 벤다이어그램을 그리기 위해 파워포인트, Keynote 같은 프로그램을 이용할 수 있습니다. 하지만, 실제 수치를 반영해서 원의 크기를 조정하고 싶을 수 있습니다. 이 때, R 의 VennDiagram 패키지를 이용할 수 있습니다. 

 

코드는 아래와 같습니다. draw.pairwise.venn 함수에 area1, area2, cross.area 에 해당하는 값을 넘겨줍니다. 이 때 주의할 점은 area1, area2 에서는 교차되는 부분을 포함하는 값을 넣어주어야 합니다. 

 

VennDiagram 패키지를 통한 벤다이어 그램 그리기 

2개 집합 벤다이어그램

  • area1 : A
  • area2 : B
  • cross.area : A∩B
library(VennDiagram)

A <- 1000
B <- 400
C <- 100

# 벤다이어그램 원 내부 수치 있도록 변경 
# scaled = FALSE 로 지정하면, 실제 수치를 고려하지 않은 벤다이어그램을 그려줌
grid.newpage()
v <- draw.pairwise.venn(area1 = A, area2 = B, cross.area = C, 
                        fill = c("light blue", "pink"), 
                        alpha = rep(0.5, 2),
                        fontfamily='Kakao Regular', scaled=TRUE)
grid.draw(v)

# cex = 0 옵션을 통해 벤다이어그램 원 내부 수치 제거
grid.newpage()
v <- draw.pairwise.venn(area1 = A, area2 = B, cross.area = C, 
                        fill = c("light blue", "pink"), 
                        alpha = rep(0.5, 2),
                        fontfamily='Kakao Regular', cex=0, scaled=TRUE)
grid.draw(v)

 

 

3개 집합이 있는 벤다이어 그램

library(VennDiagram)

area1 <- 1080
area2 <- 607
area3 <- 367
n12 <- 308
n23 <- 190
n13 <- 175
n123 <- 21

grid.newpage()
overrideTriple = TRUE
v <- draw.triple.venn(
  area1 = area1,
  area2 = area2,
  area3 = area3,
  n12 = n12,
  n23 = n23,
  n13 = n13,
  n123 = n123,
  fill = c("light blue", "pink", 'light green'), 
  alpha = rep(0.5, 3),
  cat.fontfamily='Kakao Regular',
  fontfamily='Kakao Regular', scaled=TRUE
)
grid.draw(v)

 

참고) VennDiagram 패키지는 기본적으로 숫자에 thousand point 를 찍어주지 않는다. 패키지를 조작하여 venn diagram 내부 숫자에 thousand point 를 찍는 방법은 아래와 같다. 

myvenn <- VennDiagram::draw.pairwise.venn
body(myvenn)[[46]][[3]] <- quote(function(x) {
  prettyNum(x ,big.mark=",",scientific=FALSE)
})

 

draw.pairwise.venn 대신에 myvenn 을 사용하면 된다. 

반응형
반응형

 

sparklyr 에서 bucketing 하기 (기본 R과의 비교)

 

sparkly 에서는 spark 에서 실행하기 위한 함수들이 존재한다. 물론 그룹별 집계 등의 기본적인 데이터 처리의 경우, dplyr wrapper 를 통해 추가적인 학습 없이도 바로 사용할 수 있지만, 이외의 데이터 처리의 경우 sparklyr 의 고유 함수에 대한 학습이 필요하다. 

 

본 포스팅에서는 10분위수를 기준으로 변수를 10개의 카테고리로 분류하는 bucketing 작업을 sparklyr 을 통해 해보고 기본 R 과 비교해보았다. 

 

sparklyr 에서 bucketing 하기

get_spark_connection 의 경우 spark connection 을 잡는 함수인데, 관련해서 이 포스팅을 참고하길 바란다. 이 데이터처리에서 중요함수는 sdf_quantile 과 ft_bucketizer 이다. sdf 는 spark dataframe 의 약자이고, ft는 feature transformation 의 약자이다.

 

10분위수 구하기: sdf_quantile 을 사용하면 병렬적으로 변수의 quantile 을 구해서 리턴해준다. 이 작업은 데이터를 메모리로 로드후에 R 의 기본 quantile 을 실행하는 것보다 빠르다.

 

bucket 만들기: ft_bucketizer 는 연속형 변수에 대해 bucketizing 을 해준다. 이 때, 만약 10개의 bucket 으로 나눈다고 하면, splits 에 원소가 11개인 벡터를 전달해주어야한다. 10개의 bucket 으로 나눈다고 하면, 9개의 split point 가 필요한데, 여기에 최소값과 최대값을 추가로 더해 11개라고 볼 수 있다. quantile 함수에서 9개의 decile 과 최대값을 구했으므로, 최소값인 0을 추가로 더해 split 함수에 넣어준다. 

 

bucket 이름 만들기: ft_bucketizer 함수에는 아쉽게도 bucket 의 label 을 지정하는 방법이 없다. 단지 index 만 만들어줄 뿐이다. 따라서 index 와 label 을 매핑하는 데이터프레임을 따로 만들어서 해결해볼 수 있다. quantile 의 개수만큼 seq_along 을 통해 인덱스를 만들고, names 함수를 통해 벡터의 이름을 구해서 bucket_df 라는 데이터프레임을 만든 후에, 이를 데이터와 조인하여 bucket 의 label 을 만들 수 있다. 

library(tidyverse)
library(sparklyr)

sc <- get_spark_connection()

cars <- copy_to(sc, cars, "cars", overwrite=TRUE)

val_quantile <- sdf_quantile(cars %>% filter(speed > 0), column = "speed", probabilities = seq(0.1, 1, 0.1))
val_quantile <- val_quantile[!duplicated(val_quantile, fromLast = TRUE)]

val_quantile
#    10%       20%       30%       40%       50%       60%       70%       80%       90%      100% 
#   15900     27000     35000     49900     63800     86200    113800    158310    246000 608623010 

names(val_quantile)

bucket_df <- data.frame(bucket_index = seq_along(val_quantile) - 1, bucket = names(val_quantile))
colnames(bucket_df) <- c("speed_index", "speed_cat")

# bucketing: 10분위수 총 9개와 함께, 최솟값, 최댓값을 벡터로 만들어 전달. (총 원소가 11개인 벡터)
cars <- ft_bucketizer(cars,
                        input_col = "speed",
                        output_col = "speed_index",
                        splits = c(0,val_quantile))

# spark dataframe 으로 변경
bucket_df <- sdf_copy_to(sc, bucket_df, "bucket_df", overwrite = TRUE)
cars <- left_join(cars, bucket_df, by = "speed_index")
cars %>% select(speed, speed_index, speed_cat) %>% sample_n(50)

 

기본 R 에서 10분위 bucketing 하기

기본 R dml

val_quantile <- quantile(cars %>% filter(speed > 0) %>% pull(speed), probs=seq(0.1, 1, 0.1))
val_quantile
# 10%  20%  30%  40%  50%  60%  70%  80%  90% 100% 
#   8.9 11.0 12.7 14.0 15.0 17.0 18.3 20.0 23.1 25.0 


cars$speed_cat <- if_else(cars$speed == 0, "X", 
                          as.character(cut(cars$speed, breaks = c(0,  val_quantile), labels = names(val_quantile))))
cars %>% sample_n(50)

# speed dist speed_cat
# 1     14   60       40%
# 2     13   26       40%
# 3     19   36       80%
# 4     13   34       40%
# 5     12   24       30%
# 6      4   10       10%
반응형
반응형

R Standard evaluation 과 Tidy evaluation

 

R 에서 특정 데이터프레임(df) 를 특정 열(var1,var2) 로 정렬하기 위해서는 아래와 같이 할 수 있습니다.

df %>% arrange(var1, var2)

 

 

Standard evaluation 

 

그런데 변수 이름이 동적인 경우, 즉 열 이름이 항상 같지 않고 코드 런타임에 결정되는 경우에는 표준 평가(Standard Evaluation, SE) 방법을 사용해야 합니다.

var1 <- "col1"
var2 <- "col2"

df %>% arrange(!!sym(var1), !!sym(var2))

 

 

Tidy evaluation

 

tidy evaluation 의 경우 rlang 의 {{}} (curly-curly) operation 을 사용하는 방법입니다. 그런데, 이 방법은 함수 안에서만 사용할 수 있습니다. 즉, tidy evaluation 도 동일한 기능을 수행하지만, 아래와 같이 함수 안에서만 사용할 수 있다는 제한점이 있습니다. 

my_function <- function(df, var){
  df %>% arrange({{var}})
}
반응형
반응형

 

R - 롱테일 분포의 히스토그램 그리기

 

실무를 하다보면 롱테일 분포를 많이 접하게 됩니다. 예를 들어서, 어떠한 이커머스 서비스에서 "구매 금액" 이라는 변수를 살펴보면, 대부분의 유저는 구매금액이 0~1만원 사이에 들어있지만, 일부 유저는 구매금액이 몇 백만원 심지어는 몇 억원에 이르는 경우를 심심찮게 볼 수 있습니다. 극심한 right-skewed 분포 (또는 롱테일 분포)의 예라고 볼 수 있습니다. 

 

이러한 롱테일 분포에 일반적인 히스토그램을 적용하게 되면 꼬리가 너무 길어져 가시성이 좋지 않습니다. 이런 경우에 특정 cutff 지점을 정해 따로 범주를 만들곤 합니다. 예를 들어, 구매금액이 백만원 이상인 유저는 '100만원 이상' 이라는 bucket 을 따로 만드는 것이죠. 꼬리 부분이 너무 길기 때문에 이 부분을 따로 모으는 것입니다. 

 

R 코드로는 다음과 같이 작성해볼 수 있습니다. 포인트는 raw 데이터에 적용하는 geom_hist 를 사용하는 것이 아니라, 집계 데이터를 먼저 만든 후, geom_bar 를 통해 히스토그램을 그리는 것입니다. 그리고, 집계 데이터를 만들기 위해 cut 함수를 사용합니다. 

 

R 코드

  • anal_table 데이터 프레임의 value 컬럼이 histogram 을 그리고자하는 변수입니다.
top_1_percent <- quantile(anal_table$value, 0.99, na.rm=T) # 상위 1% 경계값 찾기

# bucket size 동적으로 설정
bucket_size <- 10^ceiling(log10(top_1_percent)) # 초기 bucket size

# while loop를 통해 bucket size 조정
while(TRUE) {
  breaks <- seq(0, top_1_percent, by = bucket_size) # 상위 1% 까지의 bucket  
  if(length(breaks) > 100) break # bucket 개수가 100개 이상이면 loop 탈출
  bucket_size <- bucket_size / 10 # bucket size 재조정
}

labels <- breaks
cutoff <- max(labels)+bucket_size
# 기본적으로 break 에서 좌측을 포함하지 않고 우측을 포함함(include lowest 를 통해 가장 좌측은 포함)
# right=FALSE 를 통해 우측을 포함하지 않게 지정
anal_table$bucket <- cut(anal_table$value, breaks = seq(0, cutoff, by = bucket_size), 
                         include.lowest = TRUE, 
                         right=FALSE,
                         labels = labels)

# bucket 이 없는 경우는, cutoff 이상인 경우로, 따로 만든 bucket 에 속하도록 바꾸어줌 
anal_table <- anal_table %>% mutate(bucket = if_else(is.na(bucket), as.character(ceiling(cutoff)), bucket))
anal_table$bucket <- factor(anal_table$bucket, levels = c(labels, ceiling(cutoff)))

summary_data <- anal_table %>% group_by(bucket) %>% count()
summary_data

summary_data <- summary_data %>% mutate(var_name = var_name)

val_quantile <- quantile((anal_table %>% select(value) %>% pull), probs=seq(0.1, 1, 0.1))

quantile_keys <- names(val_quantile)
quantile_values <- unname(val_quantile)

df_quantile <- data.frame(t(quantile_values))
colnames(df_quantile) <- quantile_keys

df_avg <- anal_table %>% summarize(avg = mean(value))
df_quantile <- cbind(df_quantile, df_avg)
df_quantile <- df_quantile %>% mutate(var_name = var_name)

total_ticks <- 10  

breaks <- pretty_breaks(n = total_ticks)(range(as.numeric(as.character(summary_data$bucket))))
ggplot(summary_data, aes(x = as.numeric(as.character(bucket)), y = n)) +     
  scale_y_continuous(labels = scales::label_comma()) +     
  geom_bar(stat = "identity", fill = "black") +    
  labs(x = "X", y = "Y") +    
  scale_x_continuous(breaks = breaks,  # breaks는 pretty_breaks를 사용해 계산된 값
                     labels = breaks) +   # labels도 breaks를 사용
  theme_bw(base_size = 10, base_family = "Kakao Regular") +    
  ggtitle("Histogram from Binned Data") +      
  theme(plot.margin = margin(0.5, 0.5, 0.5, 0.5, "cm")) +  
  geom_vline(aes(xintercept = df_quantile$avg), colour = "red") +  
  annotate("text", x = df_quantile$avg, y = max(summary_data$n),  
           label = paste("평균 =", round(df_quantile$avg, 2)),  
           vjust = 2, color = "black", size=3)

 

결과 히스토그램

    • 위 코드를 통해 아래와 같이 지정된 bucket size 를 가지며, 상위 1% 이상은 하나의 bucket 으로 묶은 깔끔한 히스토그램을 그릴 수 있습니다.

 

위 코드에는 몇 가지 포인트가 있습니다. bucket size(bin)과 xtick 의 개수를 동적으로 결정한 부분인데요. 이 부분 코드를 좀 더 살펴보겠습니다. 

 

bucket size 를 동적으로 결정하기

  • bucket 의 개수가 최소 100개가 되도록 하며, bucket size 가 1, 10, 100, 1000 처럼 10의 지수형태로 만드는 방법은 아래와 같습니다. 
  • 또한 cut 함수의 labels 를 통해 label 을 이쁘게 만들어줍니다. 예를 들어 label 이 100이라고 하면, (100~199 사이의 bucket 을 의미하는 등)
# while loop를 통해 bucket size 조정
while(TRUE) {
  breaks <- seq(0, top_1_percent, by = bucket_size) # 상위 1% 까지의 bucket  
  if(length(breaks) > 100) break # bucket 개수가 100개 이상이면 loop 탈출
  bucket_size <- bucket_size / 10 # bucket size 재조정
}

labels <- breaks
cutoff <- max(labels)+bucket_size
# 기본적으로 break 에서 좌측을 포함하지 않고 우측을 포함함(include lowest 를 통해 가장 좌측은 포함)
# right=FALSE 를 통해 우측을 포함하지 않게 지정
anal_table$bucket <- cut(anal_table$value, breaks = seq(0, cutoff, by = bucket_size), 
                         include.lowest = TRUE, 
                         right=FALSE,
                         labels = labels)

 

동적 xtick 의 결정

  • 아래 코드는 총 xtick 의 개수를 10개로 고정시키고, 변수에 따라 동적으로 xtick 간격을 조정하는 코드입니다. scalse 라이브러리의 pretty_breaks 라는 함수를 사용합니다. 
library(scales)
total_ticks <- 10  
breaks <- pretty_breaks(n = total_ticks)(range(as.numeric(as.character(summary_data$bucket))))
반응형
반응형

 

rstudio server 에서 github copilot 사용하기

 

rstudio server 환경에서 github copilot 을 사용하려고 보니 아래처럼

Github Copilot integration has been disabled by the administrator 라는 문구가 떴다. 

알아보니, Rstudio Server나 Posit Workbench에서는 관리자 설정 이후 사용이 가능하다고 한다. 

 

관리자 설정 하는 방법은 아래와 같다. rsession.conf 파일을 열고 copilot-enabled=1 문구를 추가해주면 된다!

cd /etc/rstudio/
sudo vim rsession.conf

 

이렇게 Enable github copilot 옵션이 잘 나온다. 

 

반응형