Hello World! I'm Back to Blogging!
Hello World! I’m back to blogging after a long hiatus of two whole years. People have been kindly asking how’s my life going. Since I haven’t written a blog post for so long, some people may be wondering if I quietly starved to death due to the lack of a full-time job, or just grabbed the 100 million dollars that the community donated to me in 2024 and retired to a tropical island.
Just kidding. I still live in Nebraska (although sometimes I do feel like being frozen to death—this week happens to be terribly cold). As a Nebraskan, I feel obliged to “support modern digital infrastructure” for my whole life because otherwise this XKCD cartoon would be a lot less fun:
Of course, I’m not really like the Nebraskan in the cartoon with that much burden on the shoulders, but I did have had two busy years. My sincere apologies for having not responded to your emails or messages yet—I got too many of them in January 2024 alone and was unable to catch up. I will try to reply to them gradually in the coming months this year. At least I have owed a lot of thanks to people who supported me in various ways over the past two years. Anyway, here is a public thank-you note to all my sponsors:
Thank you, sponsors!
I can’t express how much I appreciate your support! Although I sent a message to my Github sponsors on Feb 6, 2024 (and updated the blog post) telling them that the sponsorship would no longer be necessary, some generous friends still continued their sponsorship. In fact, 31 of them stayed all the way through this point.
-
Current sponsors
- David Fong (@DavidPatShuiFong)
- Deborah Apthorp (@deborahapthorp)
- Eric Nantz (@rpodcast)
- Evan Brand @etbrand
- Harsh Deep (@harsh183)
- Ian Lyttle (@ijlyttle)
- Jairav Desai @jairav
- JD Long (@CerebralMastication)
- José L. Cañadas-Reche (@joscani)
- Juan Orduz (@juanitorduz)
- Kun Ren (@renkun-ken)
- Kyle G. Lundstedt (@kylelundstedt)
- Lukas Burk (@jemus42)
- Matt Pettis @mpettis
- Meimingwei Li (@YecanLee)
- Miles McBain (@MilesMcBain)
- Nicholas Knoblauch (@CreRecombinase)
- Nicola Degroot @herrshrhsjtse
- Nirav Malani (@malnirav)
- R for the Rest of Us (@rfortherestofus)
- Richard DeWald (@rdewald)
- Richard Morey @richarddmorey
- Steph Stammel (@stephstammel)
- Tim Triche, Jr. (@ttriche)
- TJ Mahr (@tjmahr)
- Xianying Tan (@shrektan)
- yilong zhang (@elong0527)
- @ludovico-beretta
- @antonpeez
- @eitsupi
- @longan2781
- plus 6 private sponsors
-
Past sponsors
- ajzhanghk @ajzhanghk
- Albert Rapp @AlbertRapp
- Alex Ho (@aluxh)
- alivaughan @AliVaughan
- Allison Horst (@allisonhorst)
- Aman Bhargava (@thedivtagguy)
- Amelia McNamara (@AmeliaMN)
- Anh N Tran @anhtr
- Anna Krystalli (@annakrystalli)
- Anthony (@anthonyatto)
- Aurélien Ginolhac (@ginolhac)
- boB Rudis (@hrbrmstr)
- Boyi Guo (@boyiguo1)
- Bruno Rodrigues (@b-rodrigues)
- Carolina Musso (@cmusso86)
- Chad You (@youcc)
- Chao Cheng (@fenguoerbian)
- Charles Y. @bongohead
- Chenhao Li @lch14forever
- Chi Zhang (@chizapoth)
- Chi-Kuang Yeh (@chikuang)
- Christophe Dervieux (@cderv)
- Claus Wilke (@clauswilke)
- Cui Tianxiang (崔天祥) (@Tianxiang-C)
- Dan Chaltiel @DanChaltiel
- Dan Zhang (@bsspirit)
- Daniel P. Palomar (@dppalomar)
- Dave Tang (@davetang)
- David Schoch (@schochastics)
- Daxuan Cheng @DaxuanCCC
- Deemah (@dmi3kno)
- Desmond Choy @DesmondChoy
- Diego H. (@dieghernan)
- Drew Clayson @drewclsn
- Dylan Anderson @danderson222
- Dylan Beaudette @dylanbeaudette
- Eduardo Leoni @leoniedu
- Ella Kaye (@EllaKaye)
- Emi Tanaka (@emitanaka)
- Emily Cibelli (@ecibelli)
- Emily Riederer (@emilyriederer)
- EmZ @mz462
- Eric Leung (@erictleung)
- Etienne Bacher (@etiennebacher)
- Eyayaw Beze (@eyayaw)
- Fan Li (@lifan0127)
- Franco Peschiera (@pchtsp)
- Freeman Wang (@freestatman)
- Gabriella Kountourides (@GabriellaS-K)
- Gang Chen (@gangchen)
- Gary Ritchie @gtritchie
- George Miranda @georgemirandajr
- GW McElfresh @GWMcElfresh
- H11 @dhcmrlchtdj
- Haizi Zheng @haizi-zh
- Hanwen Zhang @hanwengutierrez
- Hao Zhu (@haozhu233)
- Haohan Chen (@haohanchen)
- Heejung Jung @jungheejung
- Henry Q @QhenryQ
- Hiroaki Yutani (@yutannihilation)
- Howard Baik @howardbaik
- Huizhi Xu @HuizhiXu
- I-Kang Ding (@ikding)
- Iaroslav Domin (@idmn)
- imadcat @imadcat
- Ioannis Eleftheriou @yathxyz
- Istvan Albert (@ialbert)
- Jadey Ryan (@jadeynryan)
- James Azam (@jamesmbaazam)
- James Wade (@JamesHWade)
- Jarod G.R. Meng @jarodmeng
- Jasmine @certainforest
- Javier Sajuria (@jsajuria)
- Jeff Craggy (@j-craggy)
- Jeremy Allen @jeremy-allen
- Jeremy Leipzig (@leipzig)
- Jerzy Pawlowski (@algoquant)
- Jessica Burnett @trashbirdecology
- Jessica Higgins @JessKHiggins
- Jessica Louise Ray @jessicalouiseray
- Jiangtang Hu (@Jiangtang)
- Jiayi Liu (@jiayiliujiayi)
- Jiebiao Wang (@randel)
- Jim Gardner (@jimgar)
- Jingang Miao @miaojingang
- Jinhui Li (@jinhuili-lab)
- Jinlong Ru @rujinlong
- Jinyan @jinyancool
- Joan TAN (Pei Pei) @joannytan
- John Coene (@JohnCoene)
- John David Smith (@smithjd)
- John Harrold @john-harrold
- John Hu (@hutusi)
- John MacKintosh (@johnmackintosh)
- John Stanton-Geddes @johnstantongeddes
- Jonathan D. Trattner (@jdtrat)
- Josh Erickson @joshualerickson
- Josiah Parry (@JosiahParry)
- Julian During @duju211
- Julien Barnier @juba
- Junhao (Hao) WEN (@anbai106)
- Kaylee L. Davis @KayleeDavisGitHub
- Kelly N. Bodwin (@kbodwin)
- Kevin Kunzmann (@kkmann)
- Ki @kiheunch
- Kurtis Pivert, MS, CAP @kpivert
- Lavinia Lau (@Lavinialau)
- Le Zhang @lz100
- Leo @pr130
- Li Wang (@wangfan8)
- Lisa DeBruine (@debruine)
- Lisa Lendway @llendway
- Lorenzo Gaborini @lgaborini
- Lukas Gröninger @L-Groeninger
- Luke S. Morris (@morrisLuke)
- Lydia Gibson @lgibson7
- Marcio Augusto Diniz @dnzmarcio
- María Paula Caldas (@mpaulacaldas)
- Martin Mächler (@mmaechler)
- Martin van Elp (@martinvanelp)
- Marylène Henry @MaryleneH
- Mathieu Kessler @mkesslerct
- Matt Cowgill (@MattCowgill)
- Matt Dray (@matt-dray)
- Matt Kumar (@mattkumar)
- Max Kuhn (@topepo)
- Melissa Van Bussel (@melissavanbussel)
- Menly Cherisme @MenlyCSE
- Michael DeWitt (@medewitt)
- Michael Friendly (@friendly)
- Michael Luu @mluu921
- Michael Sachs (@sachsmc)
- Michael Schramm (@mps9506)
- Michael Thomas (@mthomas-ketchbrook)
- michaelcat @jimewu
- Michał Burdukiewicz (@michbur)
- Mike K Smith @MikeKSmith
- Ming Tang (@crazyhottommy)
- mnarayan (@mnarayan)
- Nan-Hung Hsieh @nanhung
- Nathan @nkbxwb
- Nathaniel Phillips (@ndphillips)
- Nick Giangreco (@ngiangre)
- Nicola Romanò (@nicolaromano)
- Nistara Randhawa (@nistara)
- Olivier Leroy (@defuneste)
- Oluwatosin Orenaike (@Otomisin)
- Ondrej Such @ondrej-such
- Pascal J. Kieslich (@PascalKieslich)
- PD-value (@PD-value)
- Philipp Thoss @pjt222
- Pierre Casadebaig (@picasa)
- Qingyang Li (@conge)
- Rahul (@rsangole)
- Ranae Dietzel (@Ranae)
- Randall Boyes (@rdboyes)
- Robert W. Walker (@robertwwalker)
- Rodrigo (@flipacholas)
- Romain François @romainfrancois
- Romain Lesur @RLesur
- Ruidong Li (@rli012)
- Ryan C Yost (@rcyost)
- Ryan Peek (@ryanpeek)
- Sam Abbott (@seabbs)
- Samuel Pawel (@SamCH93)
- Sergio Uribe (@sergiouribe)
- Sermet Pekin (@SermetPekin)
- Sharon Machlis (@smach)
- Shazia Ruybal Pesántez (@shaziaruybal)
- Shen Lu (@shenlu89)
- Starry Shi (@starrysl)
- Stathis @isthisthat
- Stephan Koenig (@stephan-koenig)
- Stephen Synchronicity (@yogat3ch)
- Steven Ge (@gexijin)
- Takaaki Masaki (@takaakimasaki)
- Tan Changde (@tanchangde)
- Tan Ho (@tanho63)
- Taym @TaymAlsalti
- Thomas Sandmann (@tomsing1)
- Thomas Vroylandt (@tvroylandt)
- Tim Taylor @TimTaylor
- Tom Mock (@jthomasmock)
- TomBen (@TomBener)
- Tracy Teal @tracykteal
- Ulrike Niemann (@ulrikeniemann)
- Uyen N @yoowhyeeen
- Victor Porcelli (@VictorPorcelli)
- vinh-tr @vinh-tr
- Vishnu @vishnuvashok
- Weibin Qu (@weibinfighting)
- Will Beasley (@wibeasley)
- Will Mackey @wfmackey
- William Chiu (@crossxwill)
- William Lai @williamlai2
- Wolfgang Huber (@wolfganghuber)
- Xiaokun Xu @xiaokunx
- Xiaosong Zhang (@xiaosongz)
- Xuan Nhat Minh Nguyen @yvesypher
- Yaohui Zeng @YaohuiZeng
- Yen-Chung Chen (@chenyenchung)
- Yifei Xiong (@Yifei-Xiong)
- yihong (@yihong0618)
- Yijun Xie (@xieyj17)
- Yiming Paul Li @yimingli
- YipengSong @YipengUva
- yisu0719 @zhouyisu
- Yixuan Qiu (@yixuan)
- Yue Jiang (@Yue-Jiang)
- Yuehting @yuehcode
- Yun YAN (@Puriney)
- Yuqing Zhang (@zhangyuqing)
- Zeki Akyol (@zekiakyol)
- Zeng Guangyu (@zenggyu)
- Zhanyu Wang @Zhanyu-Wang
- Zhian N. Kamvar (@zkamvar)
- zhouxiang (@arwenzhou)
- @ilyamusabirov
- @chainsawriot
- @vitallish
- @bergberg
- @latlio
- @fred-spaceape
- @shuailab
- @sheitin
- @evehsu
- @agneeshbarua
- @YongchaoHuang
- @awong234
- @bcBusinessStats
- @wgchoe
- @olivroy
- @huxu85
- @valvarez123
- @Luisbia
- @nathanhuangzhi
- @ckuty
- @renxiaoyo
- @ghh446
- @chathunghrn8380
- @hoaingonwiu931
- @iantbmadaleneoj
- plus 78 private sponsors
-
R code
Here is my ugly R code to retrieve names and links of my sponsors:
# use github api to find out the name and link of a username github_info = function(user) { Sys.sleep(.1) res = tryCatch( xfun::github_api(paste0('/users/', user)), error = function(e) { message('https://github.com/', user, ' not found') NULL } ) c(res$name %||% '', res$blog %||% '') } info = list() # USERS are obtained from https://github.com/sponsors/yihui for (u in USERS) { if (is.null(info[[u]])) info[[u]] = github_info(u) } info = do.call(rbind, info) # first column: name; second column: link # clean up @ links (e.g. emails) info[grepl('@', info[, 2]) & !grepl('^https://', info[, 2]), 2] = '' # add the https:// prefix if missing i = !grepl('^https?://', info[, 2]) & info[, 2] != '' info[i, 2] = paste0('https://', info[i, 2]) # if link is present but name is missing, use username i = info[, 1] == '' & info[, 2] != '' info[i, 1] = rownames(info)[i] gh_link = sprintf( '[@%s](https://github.com/%s)', rownames(info), rownames(info) ) # if user has a link, output # `[name](link) ([@user]((https://github.com/user)))`, # otherwise output # `name ([@user](https://github.com/user))` links = ifelse(info[, 1] == '', gh_link, ifelse( info[, 2] == '', sprintf('%s %s', info[, 1], gh_link), sprintf('[%s](%s) (%s)', info[, 1], info[, 2], gh_link) )) # sort by name, putting those without names at the end links = links[order(info[, 1] == '', info[, 1])] -
WeChat sponsors
I also received several donations on WeChat, but unfortunately it’s not possible to programmatically scrape the names, so I can only say that I really appreciate your generous help via WeChat Pay in 2024!
Throughout January 2024, I kept getting Github notifications about new sponsors, and felt as if it were raining dollars to my house every day! I was totally unprepared to become the second richest man here in Omaha, Nebraska (watch out, Mr. Warren Buffett, I’m catching up!). Jokes aside, I am deeply touched by the outpouring of support from so many people around the world.
For the sake of transparency, I received about 30,000 USD in total from more than 300 sponsors in the past two years. Unfortunately, I thought the money could be treated as donation and hence not subject to income tax, but when filing taxes the next year, I realized it would be too complicated to provide proofs to IRS (I received the 1099-NEC form from Github), so I just let IRS eat a part of it (not sure how much because it was mixed with my other income). Anyway, with full gratitude in my heart, I donated and gave back about $15,000 from the remaining money to various open-source projects and individuals, among which 5000 euros went to the R Foundation.
What was even more valuable than the sponsorship money was the kind words and wishes under my previous post. I regard them as the most honorable award I have ever received in my life. Thank you all so much for letting me have an idea in advance what my funeral would be like! If I were a passer, I would have thought that the guy who wrote the blog post must have died…
Contract work
On the job side, I’ve been working as a contractor for Posit (continuing to maintain the R Markdown ecosystem), Swiss Re, and Merck.
George Bakoloukas from Swiss Re was the first to offer me a contract job after I announced my departure from Posit, and I’m very grateful for his trust and support. Working with Swiss Re has been a very valuable experience to me, because it was the first time that I have dipped my toes into the (insurance) industry as a software developer to watch closely how they use the tools developed by me and others. I worked purely on the tools side, not on actuarial or insurance modeling. One funny thing is that I went to college in 2002, aiming to become an actuary, but later I found this path was too hard for me after taking courses like insurance, accounting, actuarial mathematics, and interest theory, etc., and I finally switched to statistics…
I spent most of 2024 with Swiss Re, and in 2025 I started working with Merck primarily. It was also the first time that I had walked into the pharmaceutical industry. I’d like to thank Keaven Anderson and Nan Xiao from Merck for the quick rescue. I got the job in March 2024 but worked very lightly until 2025. Similarly, I worked on the tools side and don’t have much subject-matter knowledge about pharmaceuticals, but I have enough interesting things to keep me busy.
I really appreciate the flexibility and freedom offered to me by Posit, Swiss Re, and Merck. This year I might come back to a long-time interest of mine: (interactive) data visualization. It’s still at the prototype stage, so I can’t say much about it now.
Life
Before she can read, I want to take this opportunity to “blame” it on her for consuming so much of my time since May 2024. I can’t believe my third kid is 20 months old now, nor can I believe my oldest son is about to go to middle school. You can imagine what a blessing it is to have one kid kicking a soccer ball against the wall, one constantly asking you where his crayon or glue is (and you can’t just tell him to look at .libPaths() or try install.packages(c('crayon', 'glue'))), and one reaching and smashing your keyboard while you work from home.
Now I think you can forgive me for not having responded to your messages yet.
I only traveled three times in the two years. Once to UC Berkeley to give a talk, once to visit families in China, and once to New Zealand (for the first time) to give the Ihaka lecture. One most memorable moment was when I climbed to the top of the Maungawhau (Mt Eden) volcano in Auckland (in my flip-flops, as usual). I had known the vocalno dataset in base R for nearly 20 years, and finally I got to see the real volcano in person!
My limited spare time was mostly devoted to cooking, reading, gardening, and badminton. Occasionally I also do karaoke at home, and I think I have improved a little bit (although vibrato is still hard like hell for me).
A personal project
As indicated in my previous post, I wished to pursue minimalism further. Before my daughter was born, I spent about a month on writing a lightweight version of R Markdown called litedown almost from scratch. The goal was to get rid of many dependencies (including Pandoc and knitr), with a focus on HTML output. This was an interesting experiment, and meant to be my last “*down” package. I don’t expect it to be widely adopted, although it’s powerful enough to me and I’d like to call it nearly feature-complete. Unfortunately, I haven’t had enough time to finish the documentation.
What’s next?
Working as a contractor was quite challenging for me in the beginning, but I’ve adapted to it gradually and found the proper cadence. I like the flexibility it offers, despite the instability of income, which doesn’t bother me much (e.g., when I’m sick, I’ll be on my own since there is usually no paid “sick leave” for contractors, but I can work for extra hours if I really want to make it up, and I’ve never felt I need to). This year I’ll still be working primarily for Merck.
I have many topics on my mind for future blogging, and aim to write at least one post per week. If you have suggestions on the topics, I’m all ears.
To my Chinese blog readers: many of you must have known that I batch publish all my Chinese posts once in a long while, and the last time I published was 3.5 years ago. I haven’t written a single post since 2024 until last month, when I made a decision that may surprise you—I plan to write fiction for a few years. Specifically, I’ll write fictional letters. Each letter’s topic will be from a song, and I’ll publish my karaoke recording at the end of each letter. To be honest, this feels quite embarrassing to me when I came up with the idea, because I’m not really good at singing. Nonetheless, I still want to leave some vocal records in my blog. I believe that imperfection also has its value.
I have added a very subtle “Donate” button at the bottom of each post. If you don’t look carefully, it should be easy for you to miss it, which was a deliberate choice of mine. If any of my post or software package is helpful to you, you may click the button to make a donation. I have zero expectation on how much money I can get from it, but I just want to keep the channel open for those who wish to support me in this way. Some people have suggested that I set up a paid subscription service for my blog or a private newsletter, but I’d like to keep my writings completely open and don’t want to sell anything. I think voluntary donations would be a better way to go.
That said, I do have a vague idea about a paid service—humor as a service (HaaS), with a premise that “if you don’t laugh, it’s free”. I think I’m relatively good at generating fun, but I have no idea when I’ll have time to implement this idea...
Originally I planned to write this post on Jan 4 to mark the two-year anniversary, but my daughter kindly passed a certain virus to me from her daycare, and I had to postpone it. Then I thought I should finish this post on Jan 19—my grandma’s birthday (she passed away in 2003 and I wrote a short story in memory of her in 2022), but was again interrupted by other things.
Finally, here I am. Hello world! Happy new year, everyone!