데이터저널리즘 협업 : R과 구글스프레드시트의 괜찮은 조합
"이거 CSV 안 열려요!! 인코딩 깨진 거 같은데요?"
"그때 줬던 엑셀 파일 못 찾겠어요"
"그때 뭘 수정했던 거지? 그리고 수정있어요!"
데이터저널리즘팀 열심히 노가다(?)를 하고 있다면 이런 대화가 종종 오갈 수 있다. 예를 들면, 기자 A가 필요한 데이터를 찾았고 그걸 받아 다른 누군가 R에서 작업을 하고 csv로 저장한 뒤 다시 A에게 넘겨줄 때, 위의 대화가 나올 확률은 꽤 크다. 업무환경이 Mac OS와 Windows를 함께 쓴다면 인코딩 문제로 더더욱. 이런 불필요한 과정은 쓸데없이 협업의 과정을 지저분하게 만든다. 기사가 나가고나면 기억도 안나는 엑셀 파일이 여러 개 생성되고 관리의 문제가 발생한다. 파일명에 final이 붙은 게 여러개다. 혼자 한다면 아무런 문제가 없다. 그런데 데이터저널리즘은 협업이다.
이를 해결할 수 있는 게 Jenny Bryan의 'googlesheets' 패키지가 아닐까 싶다. 그동안 살펴봤더니 생각보다 쉽고 데이터저널리즘팀에선 유용하게 쓸 수 있을 거 같다.
아래에서 설명한 코드는 여기서 확인 가능! (본인 계정으로 편집하셔야 ^^)
https://gist.github.com/woons/273367b0d5f8af6a71b858e5eddf8907
개인적으로 엑셀보다 구글시트로 대부분의 작업을 한다. 엑셀도 훌륭하지만 협업을 한다면 파일을 주고받는 엑셀보단 웹기반의 구글시트 공유가 훨씬 효과적이다. 가령 분석 내용이 바뀌고 수정 업데이트가 될 때마다 슬랙에 엑셀을 매번 올린다고 치자. 정신없이 작업하다보면 엑셀 파일 관리하는 것도 변경 내역을 확인하는 것도 쉽지 않다. 반면 구글시트는 작업 내역이 자동 저장되고 언제든 복구할 수 있으며 관리가 싶다.
그리고 구글시트는 웹&모바일 기반이라 공유 링크를 통해 언제든 볼 수 있고 공동편집이 가능하다. 다만, 40만셀 이내만 지원한다. 행이 10만 개라면 열은 4개까지 편집이 가능하단 의미다. 작업을 하다 보면 이보다 큰 데이터일 경우가 많고 기술적으로 시트를 넘어서는 작업의 경우 R을 쓸 수밖에 없는데 매번 링크를 뽑아서 공유하고 각자 구글 드라이브에서 데이터를 작업해야하는 단점이 역시 존재한다. 그래서 R과 구글시트를 유기적으로 쓸 수 있는 방법이 없을까 해서 검색해봤더니 스위스의 SRF Data팀에서도 googlesheets를 통해 협업한다고 한다. 곧 사내 데이터저널리즘 스터디에서도 공유할 겸 정리해봄.
그럼 본격적으로 googlesheets 패키지 기능에 대해서 알아보자.
gs_auth 함수를 통해서 구글 계정을 인증받는다. 인증을 받아야 해당 계정 구글 드라이브로 연결 및 시트 목록을 확인하고 수정, 생성할 수 있다. 새롭게 인증을 받거나 다른 계정으로 바꾸고 싶다면 gs_auth(new_user = TRUE)와 같이 파라미터를 추가하면 된다. 연결됐는지 궁금하다면 R Stuido 오른쪽 패널에 httr-oauth와 .gitignore 생성되는 걸 확인하자.
연결한 계정의 시트 목록을 확인해보자. gs_ls()라고만 해주면 모든 구글시트의 목록을 볼 수 있다. 모든 목록이 필요한 게 아니라 찾고 싶은 시트만 보고 싶은 게 보편적이다. 이때 regex 파마리터를 사용하면 된다. 아래 화면은 이름이 '업무추진비'로 시작하는 시트만 my_sheets 변수에 저정한 화면이다. 정규표현식을 지원해주기 때문에 정규표현식의 패턴을 적극적으로 활용하는 걸 추천. 해당 시트명, 소유자, 시트 고유키 등까지 확인 가능하다.
다만 이 글은 협업 관점에 활용하는 강조하고 있기에 팀 공용 구글드라이브를 사용한다면 시트명에 대한 규칙을 서로 공유하고 적용시키는 게 좋겠다. 각자 시트명을 마음대로 사용한다면 그것도 일이 된다... 가령 [날짜_제목_작성자] 같은 규칙?
my_sheets <- gs_ls(regex = "^업무추진비") #regex 파라미터에는 정규표현식 활용 가능
my_sheets$sheet_key
목록을 통해 시트명을 확인했다면 특정 시트에 대한 정보까지 알아보자. gs_title("업무추진비_부산광역시 강서구)를 실행시키면 아래 화면을 콘솔 창에서 볼 수 있다. 해당 시트의 세부정보다. 참고로 gs_title은 list형태로 반환된다. 제목, 소유자, 마지막 작업시간 등등 확인 가능. gs_title은 특정 시트의 정보를 확인하는 용도로 쓰면 되겠다.
df_sample <- gs_title("업무추진비_부산광역시 강서구")
# list에서 확인할 수 있는 요소들
df_sample$browser_url #공유 url
df_sample$n_ws #시트 개수
df_sample$sheet_title #구글시트명
해당 시트를 브라우저에서 보고 싶다면 이렇게!
df_sample %>% gs_browse(ws = 1) #시트별로 볼 수 있음
이제 본격적으로 작업을 해보자. 내용은 gs_read 함수를 통해 원하는 시트를 R로 가져와서 작업. 중요한 건 구글시트를 데이터프레임(data.frame)으로 가져온다. 이제 원하는 대로 모든 정제, 분석, 시각화가 가능해졌다. 워크시트가 하나뿐이라면 gs_read() 함수에 특별히 넣어줄 게 없지만 여러 개라면 가져오고 싶은 워크시트를 gs_read(ws = 1)과 같이 지정해줘야 한다.
df_sample_edit <- df_sample %>% gs_read(ws = 1)
glimpse(df_sample_edit)
#범위 설정 가능 / 가져와서 select 가능
df_sample %>% gs_read(ws = 1, range = cell_cols(1:5))
현재 드라이브에 있는 시트를 복사하거나 R에서 작업하고 있는 데이터프레임을 드라이브에 복제할 때 자주 쓰게 되는 함수. '지금 작업하고 있는 거 공용 드라이브에 올려주세요'란 부탁을 받는다면 복제해서 공유하면 유용하겠다. 혹은 Master sheets는 그대로 두고 사본을 가져갈 때도 활용해보자.
# R에서 작업하고 있는 데이터프레임 복사하기
df_sample %>% gs_copy(to = "업무추진비_부산광역시 강서구_duplicated")
# 삭제하고 싶다면
dup_df %>% gs_delete()
# 구글드라이브에 있는 시트를 드라이브 안에서 복제하기
df_sample %>% gs_copy("테스트_시트")
위에 gs_copy는 기존의 시트 사본을 만들 때 쓴다면, gs_new는 새롭게 시트를 생성해준다. 기존에는 R에서 write.csv 함수를 통해 폴더에 csv를 생성하고 그걸 다시 구글드라이브에 올린 뒤에 링크를 뽑아서 공유했다면 gs_new 함수를 쓰면 RStudio에서 작업한 데이터프레임을 바로 새롭게 구글시트로 만들어 준다. 아래는 gs_new_test_sheets란 이름의 새로운 시트를 R에서 만든 화면이다.
# title은 시트 제목, input은 시트로 변환할 대상(data.frame), trim은 해당 열까지 자르기
gs_new(title = "gs_new_test_sheets", input = df_sample_edit, trim = TRUE)
협업하는 팀 특성도 그렇고 개인적으로도 데이터 관리함에 있어서 R과 구글시트의 조합은 꽤나 좋다. 팀마다 협업 방식은 다르겠지만 만약 R과 구글시트를 함께 쓴다면 한번 고려해볼 만한 조합이다.
참고로 업무추진비 데이터 정리할 때도 시간 단축에 많은 도움을 받았다. 특정 파일 형식으로 다운로드하는 gs_download, 실시간으로 셀을 수정하는 gs_edit_cells 그리고 로컬 파일을 드라이브로 올리는 gs_upload에 대한 코드에 대한 설명은 따로 하지 않았다. Github Gist를 참고하시길!