24  커뮤니티와 오픈 사이언스

중요함께 만드는 지식 생태계

Document as Code 패러다임을 통해 오픈 사이언스 커뮤니티에 기여하고, 지식을 공유하며, 집단 지성을 발휘하는 방법을 배워봅시다.

24.1 한국 재현가능 연구 생태계

24.1.1 현황 분석

library(httr2)
library(rvest)
library(networkD3)

# 한국 오픈사이언스 현황 데이터 수집
collect_korean_open_science_data <- function() {
  
  # GitHub에서 한국 연구기관들의 오픈소스 프로젝트 현황
  korean_institutions <- c(
    "KAIST", "서울대학교", "POSTECH", "연세대학교", "고려대학교",
    "KIST", "ETRI", "한국생명공학연구원", "KRICT"
  )
  
  institution_data <- map_dfr(korean_institutions, function(inst) {
    
    # GitHub API를 통한 저장소 검색
    search_query <- paste("org:", inst, "language:R")
    
    tryCatch({
      repos <- gh::gh(
        "GET /search/repositories",
        q = search_query,
        sort = "updated",
        per_page = 100
      )
      
      tibble(
        institution = inst,
        total_repos = repos$total_count,
        r_repos = length(repos$items),
        avg_stars = mean(map_dbl(repos$items, "stargazers_count"), na.rm = TRUE),
        avg_forks = mean(map_dbl(repos$items, "forks_count"), na.rm = TRUE)
      )
    }, error = function(e) {
      tibble(institution = inst, total_repos = 0, r_repos = 0, 
             avg_stars = 0, avg_forks = 0)
    })
  })
  
  return(institution_data)
}

# 오픈 사이언스 성숙도 평가
assess_open_science_maturity <- function(institution_data) {
  
  maturity_metrics <- institution_data %>%
    mutate(
      # 다양한 지표로 성숙도 평가
      repository_score = scales::rescale(total_repos, to = c(0, 10)),
      engagement_score = scales::rescale(avg_stars + avg_forks, to = c(0, 10)),
      r_adoption_score = scales::rescale(r_repos / pmax(total_repos, 1), to = c(0, 10)),
      
      # 종합 성숙도 점수
      maturity_score = (repository_score + engagement_score + r_adoption_score) / 3,
      
      # 성숙도 등급
      maturity_level = case_when(
        maturity_score >= 7 ~ "선진",
        maturity_score >= 4 ~ "중급", 
        TRUE ~ "초기"
      )
    ) %>%
    arrange(desc(maturity_score))
  
  return(maturity_metrics)
}

# 시각화
visualize_open_science_landscape <- function(maturity_data) {
  
  # 성숙도 레이더 차트
  library(fmsb)
  
  radar_data <- maturity_data %>%
    select(institution, repository_score, engagement_score, r_adoption_score) %>%
    column_to_rownames("institution") %>%
    rbind(rep(10, 3), rep(0, 3), .)  # max, min 행 추가
  
  # 상위 5개 기관만 표시
  top_5 <- radar_data[3:7, ]
  
  radarchart(
    top_5,
    axistype = 1,
    pcol = rainbow(5, alpha = 0.6),
    pfcol = rainbow(5, alpha = 0.2),
    plwd = 2,
    title = "한국 연구기관 오픈사이언스 성숙도"
  )
  
  legend("topright", legend = rownames(top_5), 
         col = rainbow(5), lty = 1, cex = 0.8)
}

# 실행
korea_os_data <- collect_korean_open_science_data()
maturity_assessment <- assess_open_science_maturity(korea_os_data)

24.1.2 성공 사례와 모범 실무

korean_success_stories <- tribble(
  ~기관, ~프로젝트, ~설명, ~영향도, ~재현가능성_점수,
  "한국 R 사용자회", "bitPublish", "쿼토 기반 한글 출판 패키지", 95, 100,
  "서울대학교", "KoNLP", "한국어 자연어 처리 도구", 88, 85,
  "KAIST", "TensorFlow KR", "한국어 딥러닝 교육 자료", 92, 90,
  "연세대학교", "YonseiR", "통계 교육 패키지", 75, 95,
  "KIST", "BioKR", "생명정보학 분석 도구", 82, 88
)

korean_success_stories %>%
  gt() %>%
  tab_header(
    title = "한국 오픈사이언스 성공 사례",
    subtitle = "Document as Code 패러다임 적용 프로젝트"
  ) %>%
  fmt_number(
    columns = c(영향도, 재현가능성_점수),
    decimals = 0,
    pattern = "{x}점"
  ) %>%
  data_color(
    columns = c(영향도, 재현가능성_점수),
    colors = scales::col_numeric(
      palette = c("white", "lightblue", "darkblue"),
      domain = c(0, 100)
    )
  ) %>%
  tab_style(
    style = cell_text(weight = "bold"),
    locations = cells_column_labels()
  )

24.2 템플릿과 도구 공유

24.2.1 GitHub 저장소 운영

# .github/ISSUE_TEMPLATE/template_request.yml
name: 템플릿 요청
description: 새로운 쿼토 템플릿 요청
title: "[Template Request] "
labels: ["enhancement", "template"]

body:
  - type: markdown
    attributes:
      value: |
        새로운 쿼토 템플릿 요청을 환영합니다!
        
  - type: dropdown
    id: template_type
    attributes:
      label: 템플릿 유형
      description: 어떤 종류의 템플릿인가요?
      options:
        - 학술 논문
        - 기업 보고서
        - 정부 보고서
        - 프레젠테이션
        - 대시보드
        - 기타
    validations:
      required: true
      
  - type: textarea
    id: use_case
    attributes:
      label: 사용 사례
      description: 어떤 상황에서 사용할 템플릿인가요?
      placeholder: "예: 정부 R&D 과제 최종보고서 작성시 사용"
    validations:
      required: true
      
  - type: textarea
    id: requirements
    attributes:
      label: 요구사항
      description: 템플릿에 포함되어야 할 기능들
      placeholder: |
        - 한글 폰트 지원
        - 정부 양식 준수
        - 자동 목차 생성
        - 참고문헌 관리
    validations:
      required: true
      
  - type: checkboxes
    id: contribution
    attributes:
      label: 기여 의향
      description: 템플릿 개발에 기여하실 수 있나요?
      options:
        - label: 템플릿 초안 작성
        - label: 테스트 및 피드백
        - label: 문서화 작성
        - label: 유지보수 참여

24.2.2 커뮤니티 기여 가이드

# 기여 가이드

## 시작하기

### 1. 저장소 포크
```bash
# 1. GitHub에서 포크
# 2. 로컬에 클론
git clone https://github.com/yourusername/quarto-korean-templates.git
cd quarto-korean-templates

# 3. 업스트림 설정
git remote add upstream https://github.com/r2bit/quarto-korean-templates.git

24.2.3 2. 개발 환경 설정

# R 패키지 설치
Rscript -e "install.packages(c('quarto', 'rmarkdown', 'gt', 'ggplot2'))"

# Python 패키지 설치 (선택)
pip install jupyter pandas matplotlib

# 쿼토 확장 설치
quarto install extension quarto-ext/lightbox

24.2.4 3. 템플릿 개발 규칙

디렉토리 구조

templates/
├── academic/           # 학술 템플릿
│   ├── paper/
│   └── thesis/
├── business/          # 비즈니스 템플릿
│   ├── report/
│   └── presentation/
├── government/        # 정부 템플릿
│   ├── rnd-report/
│   └── policy-brief/
└── shared/           # 공통 리소스
    ├── fonts/
    ├── styles/
    └── filters/

필수 파일

각 템플릿은 다음 파일들을 포함해야 합니다:

  • template.qmd: 템플릿 파일
  • _quarto.yml: 설정 파일
  • README.md: 사용 가이드
  • example/: 사용 예제
  • tests/: 테스트 파일

코드 품질 기준

  • 모든 코드는 실행 가능해야 함
  • 한글 주석 포함
  • 스타일 가이드 준수 (tidyverse style)
  • 테스트 커버리지 80% 이상

24.2.5 4. 기여 프로세스

  1. 이슈 생성: 작업 전 이슈로 논의
  2. 브랜치 생성: feature/template-name 형식
  3. 개발 및 테스트: 로컬에서 충분한 테스트
  4. Pull Request: 상세한 설명과 스크린샷 포함
  5. 코드 리뷰: 커뮤니티 피드백 반영
  6. 병합: 승인 후 메인 브랜치에 병합

24.2.6 5. 커뮤니티 소통

  • 디스커션: 아이디어 논의와 질문
  • 이슈: 버그 리포트와 기능 요청
  • Slack: 실시간 소통 (링크)
  • 월간 미팅: 온라인 정기 모임

24.3 인정과 보상

24.3.1 기여자 인정 시스템

# 기여자 통계 추적
library(gh)

get_contributor_stats <- function(repo = "r2bit/quarto-korean-templates") {
  
  # GitHub API를 통한 기여자 정보 수집
  contributors <- gh("GET /repos/{owner}/{repo}/contributors", 
                    owner = str_split(repo, "/")[[1]][1],
                    repo = str_split(repo, "/")[[1]][2])
  
  contributor_stats <- map_dfr(contributors, function(contrib) {
    
    user_info <- gh("GET /users/{username}", 
                   username = contrib$login)
    
    tibble(
      username = contrib$login,
      name = user_info$name %||% contrib$login,
      contributions = contrib$contributions,
      avatar_url = contrib$avatar_url,
      profile_url = contrib$html_url
    )
  })
  
  return(contributor_stats)
}

# 기여자 배지 시스템
assign_contributor_badges <- function(stats) {
  
  stats %>%
    mutate(
      badge = case_when(
        contributions >= 100 ~ "🏆 Core Contributor",
        contributions >= 50 ~ "⭐ Active Contributor", 
        contributions >= 10 ~ "👍 Regular Contributor",
        TRUE ~ "🌱 New Contributor"
      ),
      level = case_when(
        contributions >= 100 ~ 4,
        contributions >= 50 ~ 3,
        contributions >= 10 ~ 2,
        TRUE ~ 1
      )
    )
}

24.4 교육과 전파

24.4.1 워크샵 프로그램

# 교육 프로그램 구조
create_workshop_curriculum <- function() {
  
  curriculum <- list(
    # 기초 과정 (4시간)
    beginner = list(
      title = "Document as Code 입문",
      duration = "4시간",
      prerequisites = "R 기초 지식",
      objectives = c(
        "Document as Code 개념 이해",
        "쿼토 기본 사용법 습득", 
        "간단한 보고서 작성"
      ),
      modules = list(
        list(
          name = "Document as Code란?",
          duration = "30분",
          type = "lecture",
          materials = c("슬라이드", "데모")
        ),
        list(
          name = "쿼토 설치와 설정", 
          duration = "45분",
          type = "hands-on",
          materials = c("설치 가이드", "실습 파일")
        ),
        list(
          name = "첫 번째 쿼토 문서",
          duration = "90분", 
          type = "hands-on",
          materials = c("템플릿", "샘플 데이터")
        ),
        list(
          name = "발표와 질의응답",
          duration = "75분",
          type = "presentation",
          materials = c("발표 템플릿")
        )
      )
    ),
    
    # 중급 과정 (8시간)
    intermediate = list(
      title = "AI와 함께하는 재현가능 연구",
      duration = "8시간",
      prerequisites = "쿼토 기초 과정 수료", 
      objectives = c(
        "AI 도구 통합 방법 학습",
        "고급 쿼토 기능 활용",
        "협업 워크플로우 구축"
      ),
      modules = list(
        list(name = "AI 통합 전략", duration = "2시간"),
        list(name = "고급 시각화", duration = "2시간"),
        list(name = "GitHub 협업", duration = "2시간"),
        list(name = "프로젝트 실습", duration = "2시간")
      )
    ),
    
    # 고급 과정 (12시간)
    advanced = list(
      title = "커뮤니티 리더 양성",
      duration = "12시간",
      prerequisites = "중급 과정 수료",
      objectives = c(
        "템플릿 개발 능력",
        "커뮤니티 기여 방법",
        "워크샵 진행 능력"
      ),
      modules = list(
        list(name = "템플릿 개발", duration = "4시간"),
        list(name = "커뮤니티 기여", duration = "4시간"), 
        list(name = "교육 진행법", duration = "4시간")
      )
    )
  )
  
  return(curriculum)
}

# 워크샵 운영 도구
create_workshop_tools <- function() {
  
  list(
    # 참가자 관리
    registration_form = "https://forms.gle/example",
    
    # 실습 환경
    setup_script = "setup-workshop.R",
    docker_image = "r2bit/quarto-workshop:latest",
    
    # 평가 도구  
    pre_assessment = create_skill_assessment("pre"),
    post_assessment = create_skill_assessment("post"),
    
    # 피드백 수집
    feedback_form = create_feedback_survey(),
    
    # 자격증 발급
    certificate_generator = create_certificate_system()
  )
}

create_skill_assessment <- function(type = c("pre", "post")) {
  
  questions <- list(
    pre = c(
      "Document as Code에 대해 알고 계신가요?",
      "쿼토를 사용해본 경험이 있나요?", 
      "버전 관리 시스템을 사용해보셨나요?",
      "AI 도구를 업무에 활용해보셨나요?"
    ),
    post = c(
      "Document as Code의 장점을 3가지 이상 설명할 수 있나요?",
      "쿼토로 기본적인 보고서를 작성할 수 있나요?",
      "GitHub를 통한 협업 방법을 이해하셨나요?", 
      "AI 도구를 윤리적으로 사용하는 방법을 아시나요?"
    )
  )
  
  return(questions[[type]])
}

24.4.2 멘토링 프로그램

# 멘토-멘티 매칭 시스템
create_mentoring_program <- function() {
  
  mentor_profiles <- tribble(
    ~멘토명, ~전문분야, ~경력, ~가능시간, ~선호방식,
    "이광춘", "Document as Code", "10년+", "주말", "온라인",
    "김데이터", "AI 통합", "5년+", "평일저녁", "오프라인", 
    "박연구", "통계분석", "8년+", "유연", "하이브리드",
    "최개발", "웹개발", "6년+", "주말", "온라인"
  )
  
  mentee_matching <- function(mentee_interests, mentor_profiles) {
    
    # 관심분야 기반 매칭 알고리즘
    matches <- mentor_profiles %>%
      rowwise() %>%
      mutate(
        match_score = calculate_compatibility(mentee_interests, 전문분야),
        compatibility = case_when(
          match_score > 0.8 ~ "매우적합",
          match_score > 0.6 ~ "적합",
          match_score > 0.4 ~ "보통",
          TRUE ~ "부적합"
        )
      ) %>%
      arrange(desc(match_score))
    
    return(matches)
  }
  
  # 멘토링 진행 도구
  mentoring_toolkit <- list(
    
    # 첫 만남 가이드
    first_meeting_checklist = c(
      "자기소개 및 목표 공유",
      "학습 스타일 파악",
      "일정 및 소통 방식 결정",
      "단기/장기 목표 설정"
    ),
    
    # 진행 단계별 가이드
    session_templates = list(
      session_1 = "기초 개념 이해",
      session_2 = "실습 환경 구축", 
      session_3 = "첫 번째 프로젝트",
      session_4 = "피드백과 개선",
      session_5 = "독립 프로젝트"
    ),
    
    # 평가 도구
    progress_tracker = create_progress_tracking_system(),
    
    # 커뮤니티 연결
    community_events = list(
      monthly_meetup = "월간 온라인 모임",
      showcase = "프로젝트 발표회", 
      hackathon = "해커톤 이벤트"
    )
  )
  
  return(list(
    matching_system = mentee_matching,
    toolkit = mentoring_toolkit
  ))
}

24.5 정책과 가이드라인

24.5.1 정부 기관 도입 전략

# 정부 기관 도입 로드맵
create_government_adoption_roadmap <- function() {
  
  roadmap <- tibble(
    단계 = c("파일럿", "확산", "정착", "고도화"),
    기간 = c("3개월", "6개월", "12개월", "지속"),
    목표 = c(
      "개념 검증 및 초기 도입",
      "부서별 확산과 교육",  
      "조직 전체 표준화",
      "지속적 개선과 혁신"
    ),
    주요활동 = list(
      c("시범 프로젝트", "교육 프로그램", "성과 측정"),
      c("템플릿 개발", "워크샵 확대", "가이드라인 제작"),
      c("정책 수립", "시스템 구축", "성과 평가"),
      c("혁신 활동", "커뮤니티 기여", "국제 협력")
    ),
    성공지표 = list(
      c("사용자 만족도 80%+", "효율성 향상 30%+"),
      c("교육 이수율 70%+", "활용 부서 50%+"),
      c("표준 준수율 90%+", "비용 절감 40%+"),
      c("혁신 사례 창출", "커뮤니티 리더십")
    )
  )
  
  return(roadmap)
}

# 도입 지원 도구
create_adoption_support_tools <- function() {
  
  list(
    # ROI 계산기
    roi_calculator = function(current_costs, new_costs, efficiency_gains) {
      
      annual_savings <- current_costs - new_costs + 
                       (current_costs * efficiency_gains / 100)
      
      roi_percentage <- (annual_savings / new_costs) * 100
      
      return(list(
        annual_savings = annual_savings,
        roi_percentage = roi_percentage,
        payback_period = new_costs / annual_savings
      ))
    },
    
    # 위험 평가 매트릭스
    risk_assessment = tribble(
      ~위험요소, ~가능성, ~영향도, ~대응전략,
      "기술적 어려움", "중간", "높음", "충분한 교육과 지원",
      "변화 저항", "높음", "중간", "점진적 도입과 소통",
      "예산 부족", "낮음", "높음", "ROI 증명과 단계적 투자",
      "인력 부족", "중간", "중간", "외부 전문가 활용"
    ),
    
    # 성공 사례 템플릿
    case_study_template = list(
      background = "도입 배경과 동기",
      implementation = "구현 과정과 방법",
      results = "정량적/정성적 성과",
      lessons_learned = "교훈과 개선점",
      recommendations = "다른 기관에의 권고사항"
    )
  )
}

24.5.2 학술 기관 파트너십

graph TD
    A[한국 R 사용자회] --> B[대학교 파트너십]
    A --> C[연구소 협력]
    A --> D[정부기관 지원]
    
    B --> B1[교육과정 개발]
    B --> B2[학생 프로젝트 지원]
    B --> B3[교수진 연수]
    
    C --> C1[공동 연구]
    C --> C2[기술 이전]
    C --> C3[인력 교류]
    
    D --> D1[정책 자문]
    D --> D2[표준 개발]
    D --> D3[교육 지원]
    
    B1 --> E[커뮤니티 성장]
    B2 --> E
    C1 --> E
    D1 --> E

24.6 국제 협력과 표준화

24.6.1 글로벌 오픈사이언스 네트워크

# 국제 협력 현황
international_partnerships <- tribble(
  ~기관, ~국가, ~협력분야, ~협력수준, ~성과,
  "R Consortium", "미국", "R 생태계", "핵심파트너", "패키지 개발",
  "rOpenSci", "국제", "오픈소스 도구", "정기협력", "코드리뷰", 
  "Carpentries", "국제", "교육프로그램", "인증강사", "워크샵운영",
  "Quarto Team", "미국", "퍼블리싱도구", "기술협력", "한글지원",
  "AsiaR", "아시아", "지역네트워크", "운영위원", "컨퍼런스"
)

# 표준화 기여 활동
standardization_contributions <- list(
  
  # 한글 지원 표준
  korean_standards = list(
    typography = "한글 타이포그래피 가이드라인",
    fonts = "웹폰트 표준 라이브러리",
    templates = "정부/기업 표준 템플릿"
  ),
  
  # 국제 표준 기여
  international_standards = list(
    quarto_i18n = "쿼토 국제화 표준",
    unicode_support = "유니코드 지원 개선",
    accessibility = "접근성 가이드라인"
  ),
  
  # 베스트 프랙티스
  best_practices = list(
    reproducibility = "재현가능 연구 체크리스트",
    collaboration = "국제 협업 워크플로우", 
    ethics = "AI 윤리 가이드라인"
  )
)

# 성과 측정
measure_international_impact <- function() {
  
  metrics <- list(
    # 다운로드 통계
    package_downloads = get_cran_downloads("bitPublish"),
    
    # GitHub 활동
    github_metrics = list(
      stars = get_github_stars("bit2r/bitPublish"),
      forks = get_github_forks("bit2r/bitPublish"), 
      contributors = get_github_contributors("bit2r/bitPublish")
    ),
    
    # 교육 영향
    training_impact = list(
      workshops_conducted = 25,
      participants_trained = 500,
      countries_reached = 12
    ),
    
    # 학술 영향
    academic_impact = list(
      papers_citing = get_citation_count(),
      conferences_presented = 8,
      collaborations_formed = 15
    )
  )
  
  return(metrics)
}

24.7 지속가능한 운영 모델

24.7.1 커뮤니티 거버넌스

# 커뮤니티 거버넌스 구조
governance:
  steering_committee:
    members: 7
    term: 2년
    responsibilities:
      - 전략적 방향 설정
      - 예산 승인
      - 정책 결정
    
  working_groups:
    - name: "기술개발"
      focus: "도구 개발과 유지보수"
      lead: "기술위원장"
      
    - name: "교육"
      focus: "교육 프로그램과 자료 개발"  
      lead: "교육위원장"
      
    - name: "커뮤니티"
      focus: "이벤트와 소통 활동"
      lead: "커뮤니티위원장"
      
    - name: "국제협력"
      focus: "해외 파트너십과 표준화"
      lead: "국제협력위원장"
  
  decision_making:
    process: "합의 기반 결정"
    voting: "필요시 다수결"
    transparency: "모든 결정 과정 공개"
    
  code_of_conduct:
    principles:
      - 존중과 포용
      - 오픈 소스 정신
      - 학습과 성장
      - 다양성 추구

24.7.2 재정 모델

create_sustainability_model <- function() {
  
  revenue_streams <- tribble(
    ~수익원, ~유형, ~예상수익, ~지속가능성, ~비중,
    "교육 프로그램", "유료", "5000만원", "높음", 40,
    "기업 컨설팅", "유료", "3000만원", "중간", 25,  
    "정부 사업", "계약", "4000만원", "중간", 30,
    "후원과 기부", "무료", "500만원", "낮음", 5
  )
  
  expenditures <- tribble(
    ~비용항목, ~금액, ~비중, ~중요도,
    "인건비", "8000만원", 65, "필수",
    "서버 및 인프라", "1000만원", 8, "필수",
    "교육 및 이벤트", "2000만원", 17, "중요",
    "마케팅", "800만원", 7, "선택",
    "기타 운영비", "700만원", 6, "선택"
  )
  
  # 재정 건전성 분석
  financial_health <- list(
    revenue_diversification = length(unique(revenue_streams$유형)),
    sustainability_score = mean(
      case_when(
        revenue_streams$지속가능성 == "높음" ~ 3,
        revenue_streams$지속가능성 == "중간" ~ 2,
        TRUE ~ 1
      ), 
      na.rm = TRUE
    ),
    break_even_point = sum(expenditures$금액) / sum(revenue_streams$예상수익)
  )
  
  return(list(
    revenue = revenue_streams,
    costs = expenditures, 
    health = financial_health
  ))
}

24.8 다음 단계

마지막 장에서는 AGI(Artificial General Intelligence) 시대를 준비하는 방법을 다루겠습니다. 인간 고유의 가치를 보존하면서 AI와 공진화하는 미래 전략을 함께 생각해보세요.


힌트실습 과제

관심 있는 오픈사이언스 프로젝트에 기여해보세요. 작은 기여부터 시작하여 점진적으로 커뮤니티의 일원이 되어보는 경험이 중요합니다.

노트커뮤니티 참여

혼자보다 함께할 때 더 큰 힘을 발휘합니다. 온라인 포럼, 오프라인 모임, 프로젝트 협업을 통해 동료 연구자들과 네트워크를 형성해보세요.