-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.json
1 lines (1 loc) · 181 KB
/
index.json
1
[{"content":"之前在VS Code中体验过Copilot的自动补全,大为震撼,但是其他IDE写R的体验都不是很好,就没有日常用起来。最近偶然一搜,发现说Rtudio里也能用Copilot的自动补全,赶紧配置了试了一下。\n注:此过程适用于Mac上英文版Rstudio,并且需要保证有良好的网络环境。\n配置过程 首先将Rstudio更新到最新版,打开Rsutio,由于登录GitHub可能需要良好的网络环境,因此需要先给Rtudio设置http代理。首先在Rtudio中运行以下命令,打开~/.Renviron处的一个配置文件。\nfile.edit(\u0026#39;~/.Renviron\u0026#39;) 在打开的文件中加入http代理设置如下,设置完后记得保存。\nhttp_proxy=http://proxy.dom.com/ #代理服务器地址,或者为http_proxy=http://ip地址:端口号 http_proxy_user=user:passwd #用户名和密码,没有用户名和密码时可省略此行 随后在顶部菜单栏选择Tools - Global Options\n最下面一栏直接就有Copilot的选项,选中并在顶部启用,再登录自己的GitHub账号。\n如果网络条件不佳,可能会遇到GitHub登录页面打不开的情况。如果是网页上显示Congratulations, you\u0026rsquo;re all set!,但是Rsutio中还是一直在加载,说明给GitHub配置的http代理有问题。\n如果步骤正确,此时会显示登录的账号名称:\n这时按说就能正常使用Copilot了。\n试用 我试着写了两行注释,其他部分都让Copilot帮我补全,运行正常。\n# generate some data to draw heatmap \u0026lt;- 这行是我写的 set.seed(123) df \u0026lt;- expand.grid(x = 1:10, y = 1:10) df$z \u0026lt;- rnorm(nrow(df)) # load the ggplot2 package library(ggplot2) # draw a heat map with ggplot \u0026lt;- 这行也是我写的 ggplot(data = df, aes(x = x, y = y, fill = z)) + geom_tile() + scale_fill_viridis_c() + theme_minimal() + theme(legend.position = \u0026#34;bottom\u0026#34;) + labs(title = \u0026#34;Heatmap of z values\u0026#34;, x = \u0026#34;x values\u0026#34;, y = \u0026#34;y values\u0026#34;, fill = \u0026#34;z values\u0026#34;) 画出的图\n赶快体验一下吧。\n","permalink":"https://yorks0n.github.io/posts/rstudio_with_copilot/","summary":"希望我不是最后一个知道的。","title":"Rstudio也能用GitHub Copilot了"},{"content":"最近太忙了,半个多月前就打完了草稿,但一直没空更新,趁偷闲更新一下。\niPad mini A17 Pro 赶上国补的85折买的,首发破发的苹果还得是国补。虽然是不用加400就能上air的价格,但早就想买个mini日常娱乐用。到手后又配了大康的膜和咸鱼淘的微瑕紫色双面夹,发现不如橙色的亮眼,有些后悔,还是今年新出的紫色更好看。贴膜后屏幕摸起来不再涩涩的,也不担心丢在桌子柜子上刮到机器了。非常满意,几乎每天回到家就捧着它。现在每天白天看屏幕的时间太久了,回家看手机的时候总会觉得屏幕太小,很疲惫,mini的大小就刚刚好,既够大,又不至于大到不想捧着它。大部分时候我拿它看看b站的视频,或是看会儿直播(之前只用手机就不太会看直播,看屏幕久了太累了)。同时,用mini看微信读书也非常舒适,之前曾经在手机上用过,但那个屏幕太小,读书总不太得劲,宁可去用kindle看。我一直觉得看书这种事,偶尔导入一下书,其他时候只用kindle也不大麻烦,但现在发现用起来方便真的太重要了,能极大促进我拿起来读书的欲望,甚至让我第一次去充了个微信读书会员。\ncaldigit TS3 plus雷电拓展坞 不知道是最近压力大还是双十一前后,购物欲望老强了,新的Mac mini M4也让人看着就心动。然而我的M2 16+512才买一年多,用着也没啥不妥,纠结之下就没买新的Mac mini。于是寻思着买点其他的给自己一点快乐,某天突然想到我的Mac mini的HDMI接口可能是有点松垮,加上经常会去机器上插拔优盘等,于是老会碰到HDMI线,让屏幕黑屏,这时候就要重新去动一动那个线,并且此趋势近期有愈演愈烈的倾向,便打算买个扩展坞。既然要买,准备买个雷电接口的,可那时去看群友挂在闲鱼上的品相价格俱佳的TS4已经被卖掉了,搜了搜有洋垃圾plugable实在不咋好看,就降了降六百多收了个闲鱼上的TS3 plus。Caldigit的这几个扩展坞还都是DP的接口,相比HDMI接口也更稳固一些。虽然旧的这款是DP 1.2的,好在接我4K 60 hz的旧LG显示器也完全足够了。顺便收拾了一下桌子,把Mac mini放在升降台下,扩展坞放在升降台上,插拔优盘很方便,也不再会黑屏了。把我之前的一个爱国者固态也长期插在扩展坞上,休眠或重启后也不会断连,美中不足是扩展坞老是温温的,不知道夏天会不会太热。\n","permalink":"https://yorks0n.github.io/posts/buy_11/","summary":"\u003cp\u003e最近太忙了,半个多月前就打完了草稿,但一直没空更新,趁偷闲更新一下。\u003c/p\u003e\n\u003ch2 id=\"ipad-mini-a17-pro\"\u003eiPad mini A17 Pro\u003c/h2\u003e\n\u003cp\u003e赶上国补的85折买的,首发破发的苹果还得是国补。虽然是不用加400就能上air的价格,但早就想买个mini日常娱乐用。到手后又配了大康的膜和咸鱼淘的微瑕紫色双面夹,发现不如橙色的亮眼,有些后悔,还是今年新出的紫色更好看。贴膜后屏幕摸起来不再涩涩的,也不担心丢在桌子柜子上刮到机器了。非常满意,几乎每天回到家就捧着它。现在每天白天看屏幕的时间太久了,回家看手机的时候总会觉得屏幕太小,很疲惫,mini的大小就刚刚好,既够大,又不至于大到不想捧着它。大部分时候我拿它看看b站的视频,或是看会儿直播(之前只用手机就不太会看直播,看屏幕久了太累了)。同时,用mini看微信读书也非常舒适,之前曾经在手机上用过,但那个屏幕太小,读书总不太得劲,宁可去用kindle看。我一直觉得看书这种事,偶尔导入一下书,其他时候只用kindle也不大麻烦,但现在发现用起来方便真的太重要了,能极大促进我拿起来读书的欲望,甚至让我第一次去充了个微信读书会员。\u003c/p\u003e\n\u003ch2 id=\"caldigit-ts3-plus雷电拓展坞\"\u003ecaldigit TS3 plus雷电拓展坞\u003c/h2\u003e\n\u003cp\u003e不知道是最近压力大还是双十一前后,购物欲望老强了,新的Mac mini M4也让人看着就心动。然而我的M2 16+512才买一年多,用着也没啥不妥,纠结之下就没买新的Mac mini。于是寻思着买点其他的给自己一点快乐,某天突然想到我的Mac mini的HDMI接口可能是有点松垮,加上经常会去机器上插拔优盘等,于是老会碰到HDMI线,让屏幕黑屏,这时候就要重新去动一动那个线,并且此趋势近期有愈演愈烈的倾向,便打算买个扩展坞。既然要买,准备买个雷电接口的,可那时去看群友挂在闲鱼上的品相价格俱佳的TS4已经被卖掉了,搜了搜有洋垃圾plugable实在不咋好看,就降了降六百多收了个闲鱼上的TS3 plus。Caldigit的这几个扩展坞还都是DP的接口,相比HDMI接口也更稳固一些。虽然旧的这款是DP 1.2的,好在接我4K 60 hz的旧LG显示器也完全足够了。顺便收拾了一下桌子,把Mac mini放在升降台下,扩展坞放在升降台上,插拔优盘很方便,也不再会黑屏了。把我之前的一个爱国者固态也长期插在扩展坞上,休眠或重启后也不会断连,美中不足是扩展坞老是温温的,不知道夏天会不会太热。\u003c/p\u003e","title":"双十一买了啥"},{"content":"文献积累——学术生涯的外部记忆 在科研之路上,你想要积累哪些知识?\n有没有过这样的经历?你正在准备一个重要的研究报告或论文,需要找到那篇关键的文献,但却在堆积如山的文件和资料中找不到它。或者你读过一篇很好的文献,但当你想引用它的时候,你却忘记了它的具体内容。\n在一些科幻作品中,存在“外部记忆装置”的设定,其中的人物往往不将全部信息记在脑中,而是在需要时从外部记忆中调取内容。如今我们的现实已经与之颇有些相似:我们不会记住每一个具体的知识细节,浩如烟海的内容爆炸也不允许我们这么做,但我们通常知道去哪里找到这部分知识。当下,电脑和手机已经成为我们肢体的延伸,搜索引擎强大的检索功能,赋予我们按照需求取用知识的能力。\n而在科研道路上,经年累月的学习不但锻炼着我们的实验技能,积累下来的知识同样是我们学习道路上宝贵的财富。在此过程中,我们读过的每一篇文献,被我们记住的不是其中具体的语句,而是各项工作中的主要结果和结论。但在有些时候,比方说想参考某个方法做个相似的实验,或是写作背景综述时,我们会回忆起曾经看过的文章,会去找出最原始的文章查看更多细节。这时,曾经整理过的文献便摇身一变,担当起我们学术生涯外部记忆的职责。\n为什么文献常常乱作一团? 那么,为什么明明每一篇文献都有明确的主题和关键词,整理起来却依旧存在非常多困难呢?举个例子,说有一篇文章,“如何做出一盘无敌好吃的小炒肉”,里面从肉的选购、处理、调味到烹饪方法一应俱全。你看完后,觉得非常好,这么棒的技巧我一定要学会,你会把它收在哪?\n菜谱 —— 没错,再怎么说这也是个菜谱,放这准没错 年夜饭菜单 —— 今年的年夜饭由你掌勺,正巧家里有人最爱吃小炒肉,放这备着 如何买菜 —— 本文的肉类选购部分讲得太清晰了,常常温习准能以后买菜不踩坑 常用调味料 —— 刚搬了新家,需要买些调料,你正在想买什么合适 …… 如果从上面几点出发,这些归类方式似乎都有各自的道理,这也是信息管理有时会比较困难的原因:在不同的场景下,相同的内容可以有不同的分类方式,并且往往没有对错之分。\n因此我觉得,好的文献管理思路比工具更重要。现在能用来做文献管理的工具层出不穷,Endnote也好,Zotero也好,网上都能找到非常详细的用法教程。但是假如只有工具,没有恰当的内容组织思路,那工具里的文献也会堆成一团乱麻。我更想提供一个框架,让每个人可以根据自己的需要,将内容以一种便于寻找的方式组织起来。\n我们的目的:让内容便于被找到。\n什么是PARA方法? 在之前的很长时间里,我一直隐约觉得,自己整理的文献资料库,其中的各个文件夹彼此之间没有明确的分隔关系,以至于想存一篇新文章的时候,要纠结半天放在哪。纠结完存进去后,要找来用的时候又找不出来这篇文章了。后来偶然间了解到了一种称为PARA的信息整理方法,它将内容分类为项目、领域与资源几个大类。或许它不是最好最完美的,但是相比于没有框架的时候,已经有了质的飞跃。也因此,我今天将其分享给大家,如果你们也遇到过相似的困扰,可以尝试一下这个方法。\n所谓PARA,其实是Tiago Forte提出的一种组织信息的思路。其实,PARA分别代表Projects(项目)、Areas(领域)、Resources(资源)和Archives(归档)。\n这样讲可能比较抽象,举个我自己的例子,比如我关注基因组学和生物信息学,我所做的课题也与之有关,相关分析做得好可以帮助我产出成果,做不好则毕业都很费劲,我需要为此负责,因此基因组学就可称作我关注的一个领域。同时,我的课题是一个物种的基因组测序项目,从我开始着手找资料开始,历经测序、组装和分析,直到文章发表结束,因为能划分出非常明确的开始和结束时间,因此这个课题属于一个项目。同时,我又对平面设计比较感兴趣,会去看一些相关的书籍和学习资料,这些东西我看着会觉得很有意思,但如果不看也不太影响我完成课题,于是可以算作资源。另外,假如我之前有个项目已经做完了,已经完成项目的内容我当然不需要经常去关注,那它就可以被划到归档。\n然而,领域与项目、资源之间并不是独立的,而是可以互相滋养\n通过项目来打磨提升领域——比方说,我关注基因组学,但是只靠看一堆基因组相关的文章提升实在有限,必须要自己去实际做一些项目来锻炼,在项目中熟悉各部分的流程,并实际掌握操作的技能。\n通过资源支撑领域域 ——我们日常看的各种文章、资料,大部分都属于资源而非领域,正如上面讲到,我们没法只靠读来掌握某些内容。但是每天的精力是有限的,假如分配给太多方面,面面俱到也很困难。于是更好的方法是基于领域 (或者将来潜在的 Area)作为精进的方向,然后把资源当做领域的基石和养分。\n如何将PARA方法应用在组织文献中 不过,要想用这种方式来管理自己的文献,首先需要花点时间想一想,对自己来说,究竟想要积累哪些知识?\n这里先来讲讲我的,我在项目中放入了刚刚提到的物种测序项目,因为这是我的课题;在领域中包含了基因组学,数据可视化,生物信息学等,因为这是我的专业方向,同时与我的课题息息相关;在资源中放入了平面设计,认知与思维方式,效率,以及语言,因为我对这些方面非常感兴趣;最后,归档中有我之前做过的一个项目,某个物种的耐盐基因筛选,它已经结束了,于是进了归档。\n这个清单的长度当然没有明确的限制,但是当你打算往自己关注的领域里放入二三十个主题时,也得掂量掂量有没有足够的精力。创建一个清晰的清单,能让你对自己想要积累知识的边界更加明确,就可以据此有意识地、战略性地决定看或者不看某篇文章,决定某个拖了很久的工作究竟是赶快弥补还是尽快放弃它。 相反,如果你不为自己定义清单,就会被不断拉着、推到别人的项目中去。比如,CNS新出了一堆顶刊文章,你看不看,看哪些?\n可以看到,其中有几部分是和科研有关的,另一部分则是兴趣使然。和科研有关的部分,我就时常需要读些论文,并将对应的知识积累起来。\n然后,你需要选择一个用来管理文献的工具。我选择了Zotero作为文献管理的工具,它大概长这样。左边的区域包括以文件夹形式组织的目录,下方是给文献打上的标签,中间区域是文献的标题、作者、期刊、年份等信息,右边则是选中某条文章后的详细信息。\n你也完全可以选择别的工具,比如更为老牌的Endnote,可能会是更多人包括大家的导师的第一选择,生命科学图书馆之前是有Endnote可以下载的。我讲的与选择特定工具并不关联,你可以任意选择喜欢的工具,并在那个工具中实现相似的效果。\n接下来需要在文献管理软件中根据选择好的项目、领域、资源创建大类。\n假如你已经在使用这样的文献管理工具,已经积累了一些文章,但是它们有些混乱。可以这样重新开始:将所有现有的文章移动到一个新的文件夹,命名为归档和当前日期,然后开始接下来的步骤。因为与其花费大量时间整理它们,将来也不一定用得到,反而可能让你失去开始的契机。因此不如和它们暂时告别,不必担心丢失任何东西,它们都还在,当需要的时候还可以通过搜索找到它们。\n让我们继续,在管理软件的目录下,按照项目、领域、资源和归档创建四个大类,并将大类下面为你选定的主题再分别创建文件夹。记住,一开始只需要创建到每个大类下的主题就可以了,只有当在你在这个主题下积累了一定的内容,感觉需要进一步细分时,才创建新的文件夹,可以最大程度避免文件夹的冗余和混乱。\n这里还有两个小技巧,其一是默认的文件夹可能会按字母排序,你可以在前面加上数字,让它们按你想要的顺序排序。其二是我还为其添加了一个收集箱(Inbox),放在所有类别最前面,这样当遇到某篇可能感兴趣的文章时,可以先将其收进收集箱,等看完后判断一下,是将它储存起来以备将来查阅,还是和我需要的知识不太相关,因此直接删除。\n随后,可以进一步按照内容将某个项目拆分为更细的子类别。比如这里以我比较熟悉的基因组测序项目为例,它由前期的基因组调研、组装注释,以及下游的一系列分析组成。\n我可以按照项目推进的阶段,将其拆分为一个个子项目,比如在调研阶段,我看的文章主要是基因组大小、染色体信息、近缘物种等资料,在组装注释阶段,需要看各种软件的使用方法,而在分析阶段,则需要阅读许多现有文章,总结其分析流程和方法。\n这里强调两个实用的功能,一个是标签,我给一部分比较常用的标签设置了颜色,让其显示在文章处,比如标记文章是否已读,读完觉得文章是否重要。还可以按照文章类型标记标签,比如综述类、方法类,或是将文章归类为特定主题,一切都以自己将来找某个文章时是否方便为依据。\n另一个实用的功能是Zotero里的Short Title功能,可以看向右图中中间这一列。这一列默认是不显示的,需要在调整显示的列中将其显示出来。可以看到我给不少文章加上了短标题,这样瞄一眼就能找到我想找的文章。\n虽然这里只写了项目,但是领域、资源类别下同理进行划分。最后记得将已经完成的项目,放入归档中。\n总结一下,PARA方法实际是提供了一种归类思路,将所有的内容以某种分类规则,构建成了树状的结构。树状结构层次清晰,利于我们记忆,检索起来也非常方便。而文献管理软件中标签的存在,让文章间有了更复杂的联系,组建成网状结构,允许我们以更复杂的方式进行筛选:比如我想选择全部没有读过的、综述类型的、和细胞壁相关的文章,只需要同时选中这几个标签就能找到。\n一些小建议 再提几个可能能让文章不会过度混乱的小建议。\n保持克制,不当仓鼠\n我们首先需要的,是考虑清楚自己打算积累哪些知识。我最开始就有过一阵这样子的阶段,每次看到一篇文章都想先将其保存下来,想着“万一用的上呢”。 仿佛保存过文章,我就有拥有了这部分知识。加上Zotero中保存文章实在是非常方便,点一下浏览器的收藏插件就可以将文章存下来,因此保存的文章越来越多,但其实大部分文章都没怎么仔细看过,文章越来越多,文档库也越来越混乱,从中找文章的过程也变得复杂。直到某个时候,我发现保存下来完全没看过的文章很多,我既看不完它们,也没法将它们用起来。后来才意识到,一篇文章如果只是被下载下来,存在电脑里,并不意味着我就拥有了这部分知识。因此盲目地收藏文章并不可取,反而很容易因为囤积了太多,使计划稍后仔细读一读的文章变成再也不读。\n定期整理\n其次,不要想一次性设计出一个一劳永逸的资料管理系统。这也是我有过的困扰,将文献保存下来后,每次随便地想一个合适的文件夹储存它们。这样过了一段时间,我有好多好多并列的文件夹,但是我甚至不记得每个文件夹里存了些什么,不少文件夹的内容还互相有所交叉。终于某一天我下定决心,把所有的文件夹整理了一遍,能合并的合并,很多没看过、用不上的文章都删掉,这才感觉清爽了不少。并且意识到,很多最开始文件夹组织上的混乱,来源于课题早期对于整体脉络的不清晰,同时处在课题的探索阶段,什么都看一点,才弄出了一大堆各种内容的文件夹;到了课题中后期,主要内容已经明确,因为脉络不清晰造成的混乱也就自然而然地解决了。也正因如此,我觉得只有定期整理一下,让文献之间的结构伴随着你的成长,像植物那样逐渐生长出来,才能得到最适合你的文献管理结构。\n不必面面俱到。\n有些时候某一篇文章,已经放在项目下的一个文件夹里了,你可能会纠结,用不用再去其他符合这篇文章气质的文件夹再放一份?我也曾纠结过这一点,感觉不把每个可能相关的文件夹都放一份,将来找的时候万一找不到就很麻烦。 而现在的我,对此建议是保持克制,只把文章放在你当前需要用到的类别中。因为后来想明白了,收集是为了之后的使用,并不为了打造一个事无巨细的图书馆。等将来的某一天真要找这篇文章的时候,回想到曾经在做某个项目的过程中看过,然后就会去项目下面根据所属的类别找到这篇文章,到那时如果有在别处用到它的需求,比如说你有了一个新的项目,在写一篇新的综述,再将其放在对应的合集中就可以了。也得益于使用了文献管理软件,在多个文件夹下存在的同一篇文章,并不会分散成多个文件,而是共用相同的条目信息,因此只要是同一篇文章,哪怕在每个文件夹中都放一份,最终在数量上也只算是有一篇,它们的笔记也都是共通的。\n补充阅读 我的科研软件流分享 - 少数派\n解决科研人痛点的大突破——Zotero 6.0 亮点速览 - 少数派\n","permalink":"https://yorks0n.github.io/posts/para_and_zotero/","summary":"\u003ch2 id=\"文献积累学术生涯的外部记忆\"\u003e文献积累——学术生涯的外部记忆\u003c/h2\u003e\n\u003cblockquote\u003e\n\u003cp\u003e在科研之路上,你想要积累哪些知识?\u003c/p\u003e\u003c/blockquote\u003e\n\u003cp\u003e有没有过这样的经历?你正在准备一个重要的研究报告或论文,需要找到那篇关键的文献,但却在堆积如山的文件和资料中找不到它。或者你读过一篇很好的文献,但当你想引用它的时候,你却忘记了它的具体内容。\u003c/p\u003e\n\u003cp\u003e在一些科幻作品中,存在“外部记忆装置”的设定,其中的人物往往不将全部信息记在脑中,而是在需要时从外部记忆中调取内容。如今我们的现实已经与之颇有些相似:我们不会记住每一个具体的知识细节,浩如烟海的内容爆炸也不允许我们这么做,但我们通常知道去哪里找到这部分知识。当下,电脑和手机已经成为我们肢体的延伸,搜索引擎强大的检索功能,赋予我们按照需求取用知识的能力。\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"images/image.png\" alt=\"image.png\" /\u003e\n\u003c/p\u003e\n\u003cp\u003e而在科研道路上,经年累月的学习不但锻炼着我们的实验技能,积累下来的知识同样是我们学习道路上宝贵的财富。在此过程中,我们读过的每一篇文献,被我们记住的不是其中具体的语句,而是各项工作中的主要结果和结论。但在有些时候,比方说想参考某个方法做个相似的实验,或是写作背景综述时,我们会回忆起曾经看过的文章,会去找出最原始的文章查看更多细节。这时,曾经整理过的文献便摇身一变,担当起我们学术生涯外部记忆的职责。\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"images/image%201.png\" alt=\"image.png\" /\u003e\n\u003c/p\u003e\n\u003ch2 id=\"为什么文献常常乱作一团\"\u003e为什么文献常常乱作一团?\u003c/h2\u003e\n\u003cp\u003e那么,为什么明明每一篇文献都有明确的主题和关键词,整理起来却依旧存在非常多困难呢?举个例子,说有一篇文章,“如何做出一盘无敌好吃的小炒肉”,里面从肉的选购、处理、调味到烹饪方法一应俱全。你看完后,觉得非常好,这么棒的技巧我一定要学会,你会把它收在哪?\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e菜谱 —— 没错,再怎么说这也是个菜谱,放这准没错\u003c/li\u003e\n\u003cli\u003e年夜饭菜单 —— 今年的年夜饭由你掌勺,正巧家里有人最爱吃小炒肉,放这备着\u003c/li\u003e\n\u003cli\u003e如何买菜 —— 本文的肉类选购部分讲得太清晰了,常常温习准能以后买菜不踩坑\u003c/li\u003e\n\u003cli\u003e常用调味料 —— 刚搬了新家,需要买些调料,你正在想买什么合适\u003c/li\u003e\n\u003cli\u003e……\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e如果从上面几点出发,这些归类方式似乎都有各自的道理,这也是信息管理有时会比较困难的原因:在不同的场景下,相同的内容可以有不同的分类方式,并且往往没有对错之分。\u003c/p\u003e\n\u003cp\u003e因此我觉得,好的文献管理思路比工具更重要。现在能用来做文献管理的工具层出不穷,Endnote也好,Zotero也好,网上都能找到非常详细的用法教程。但是假如只有工具,没有恰当的内容组织思路,那工具里的文献也会堆成一团乱麻。我更想提供一个框架,让每个人可以根据自己的需要,将内容以一种便于寻找的方式组织起来。\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e我们的目的:让内容便于被找到。\u003c/p\u003e\u003c/blockquote\u003e\n\u003ch2 id=\"什么是para方法\"\u003e什么是PARA方法?\u003c/h2\u003e\n\u003cp\u003e在之前的很长时间里,我一直隐约觉得,自己整理的文献资料库,其中的各个文件夹彼此之间没有明确的分隔关系,以至于想存一篇新文章的时候,要纠结半天放在哪。纠结完存进去后,要找来用的时候又找不出来这篇文章了。后来偶然间了解到了一种称为PARA的信息整理方法,它将内容分类为项目、领域与资源几个大类。或许它不是最好最完美的,但是相比于没有框架的时候,已经有了质的飞跃。也因此,我今天将其分享给大家,如果你们也遇到过相似的困扰,可以尝试一下这个方法。\u003c/p\u003e\n\u003cp\u003e所谓PARA,其实是Tiago Forte提出的一种组织信息的思路。其实,PARA分别代表Projects(项目)、Areas(领域)、Resources(资源)和Archives(归档)。\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"images/image%202.png\" alt=\"image.png\" /\u003e\n\u003c/p\u003e\n\u003cp\u003e这样讲可能比较抽象,举个我自己的例子,比如我关注基因组学和生物信息学,我所做的课题也与之有关,相关分析做得好可以帮助我产出成果,做不好则毕业都很费劲,我\u003cstrong\u003e需要为此负责\u003c/strong\u003e,因此\u003cstrong\u003e基因组学\u003c/strong\u003e就可称作我关注的一个\u003cstrong\u003e领域\u003c/strong\u003e。同时,我的课题是一个\u003cstrong\u003e物种的基因组测序项目\u003c/strong\u003e,从我开始着手找资料开始,历经测序、组装和分析,直到文章发表结束,因为能划分出非常\u003cstrong\u003e明确的开始和结束时间\u003c/strong\u003e,因此这个课题属于一个\u003cstrong\u003e项目\u003c/strong\u003e。同时,我又对\u003cstrong\u003e平面设计\u003c/strong\u003e比较\u003cstrong\u003e感兴趣\u003c/strong\u003e,会去看一些相关的书籍和学习资料,这些东西我看着会觉得很有意思,但如果不看也不太影响我完成课题,于是可以算作\u003cstrong\u003e资源\u003c/strong\u003e。另外,假如我之前有个项目已经做完了,已经完成项目的内容我当然不需要经常去关注,那它就可以被划到归档。\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"images/image%203.png\" alt=\"image.png\" /\u003e\n\u003c/p\u003e\n\u003cp\u003e然而,领域与项目、资源之间并不是独立的,而是可以互相滋养\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e通过项目来打磨提升领域\u003c/strong\u003e——比方说,我关注\u003cstrong\u003e基因组学\u003c/strong\u003e,但是只靠看一堆基因组相关的文章提升实在有限,必须要自己去实际做一些项目来锻炼,在项目中熟悉各部分的流程,并实际掌握操作的技能。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e通过资源支撑领域域\u003c/strong\u003e ——我们日常看的各种文章、资料,大部分都属于资源而非领域,正如上面讲到,我们没法只靠读来掌握某些内容。但是每天的精力是有限的,假如分配给太多方面,面面俱到也很困难。于是更好的方法是\u003cstrong\u003e基于领域 (或者将来潜在的 Area)作为精进的方向,然后把资源当做领域的基石和养分\u003c/strong\u003e。\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"images/image%204.png\" alt=\"image.png\" /\u003e\n\u003c/p\u003e\n\u003ch2 id=\"如何将para方法应用在组织文献中\"\u003e如何将PARA方法应用在组织文献中\u003c/h2\u003e\n\u003cp\u003e不过,要想用这种方式来管理自己的文献,首先需要花点时间想一想,对自己来说,究竟想要积累哪些知识?\u003c/p\u003e\n\u003cp\u003e这里先来讲讲我的,我在项目中放入了刚刚提到的物种测序项目,因为这是我的课题;在领域中包含了基因组学,数据可视化,生物信息学等,因为这是我的专业方向,同时与我的课题息息相关;在资源中放入了平面设计,认知与思维方式,效率,以及语言,因为我对这些方面非常感兴趣;最后,归档中有我之前做过的一个项目,某个物种的耐盐基因筛选,它已经结束了,于是进了归档。\u003c/p\u003e\n\u003cp\u003e这个清单的长度当然没有明确的限制,但是当你打算往自己关注的领域里放入二三十个主题时,也得掂量掂量有没有足够的精力。创建一个清晰的清单,能让你对自己想要积累知识的边界更加明确,就可以据此有意识地、战略性地决定看或者不看某篇文章,决定某个拖了很久的工作究竟是赶快弥补还是尽快放弃它。 相反,如果你不为自己定义清单,就会被不断拉着、推到别人的项目中去。比如,CNS新出了一堆顶刊文章,你看不看,看哪些?\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"images/image%205.png\" alt=\"image.png\" /\u003e\n\u003c/p\u003e\n\u003cp\u003e可以看到,其中有几部分是和科研有关的,另一部分则是兴趣使然。和科研有关的部分,我就时常需要读些论文,并将对应的知识积累起来。\u003c/p\u003e\n\u003cp\u003e然后,你需要选择一个用来管理文献的工具。我选择了Zotero作为文献管理的工具,它大概长这样。左边的区域包括以文件夹形式组织的目录,下方是给文献打上的标签,中间区域是文献的标题、作者、期刊、年份等信息,右边则是选中某条文章后的详细信息。\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"images/image%206.png\" alt=\"image.png\" /\u003e\n\u003c/p\u003e\n\u003cp\u003e你也完全可以选择别的工具,比如更为老牌的Endnote,可能会是更多人包括大家的导师的第一选择,生命科学图书馆之前是有Endnote可以下载的。我讲的与选择特定工具并不关联,你可以任意选择喜欢的工具,并在那个工具中实现相似的效果。\u003c/p\u003e\n\u003cp\u003e接下来需要在文献管理软件中根据选择好的项目、领域、资源创建大类。\u003c/p\u003e\n\u003cp\u003e假如你已经在使用这样的文献管理工具,已经积累了一些文章,但是它们有些混乱。可以这样重新开始:将所有现有的文章移动到一个新的文件夹,命名为归档和当前日期,然后开始接下来的步骤。因为与其花费大量时间整理它们,将来也不一定用得到,反而可能让你失去开始的契机。因此不如和它们暂时告别,不必担心丢失任何东西,它们都还在,当需要的时候还可以通过搜索找到它们。\u003c/p\u003e\n\u003cp\u003e让我们继续,在管理软件的目录下,按照项目、领域、资源和归档创建四个大类,并将大类下面为你选定的主题再分别创建文件夹。记住,一开始只需要创建到每个大类下的主题就可以了,只有当在你在这个主题下积累了一定的内容,感觉需要进一步细分时,才创建新的文件夹,可以最大程度避免文件夹的冗余和混乱。\u003c/p\u003e\n\u003cp\u003e这里还有两个小技巧,其一是默认的文件夹可能会按字母排序,你可以在前面加上数字,让它们按你想要的顺序排序。其二是我还为其添加了一个收集箱(Inbox),放在所有类别最前面,这样当遇到某篇可能感兴趣的文章时,可以先将其收进收集箱,等看完后判断一下,是将它储存起来以备将来查阅,还是和我需要的知识不太相关,因此直接删除。\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"images/image%207.png\" alt=\"image.png\" /\u003e\n\u003c/p\u003e\n\u003cp\u003e随后,可以进一步按照内容将某个项目拆分为更细的子类别。比如这里以我比较熟悉的基因组测序项目为例,它由前期的基因组调研、组装注释,以及下游的一系列分析组成。\u003c/p\u003e\n\u003cp\u003e我可以按照项目推进的阶段,将其拆分为一个个子项目,比如在调研阶段,我看的文章主要是基因组大小、染色体信息、近缘物种等资料,在组装注释阶段,需要看各种软件的使用方法,而在分析阶段,则需要阅读许多现有文章,总结其分析流程和方法。\u003c/p\u003e\n\u003cp\u003e这里强调两个实用的功能,一个是标签,我给一部分比较常用的标签设置了颜色,让其显示在文章处,比如标记文章是否已读,读完觉得文章是否重要。还可以按照文章类型标记标签,比如综述类、方法类,或是将文章归类为特定主题,一切都以自己将来找某个文章时是否方便为依据。\u003c/p\u003e\n\u003cp\u003e另一个实用的功能是Zotero里的Short Title功能,可以看向右图中中间这一列。这一列默认是不显示的,需要在调整显示的列中将其显示出来。可以看到我给不少文章加上了短标题,这样瞄一眼就能找到我想找的文章。\u003c/p\u003e\n\u003cp\u003e虽然这里只写了项目,但是领域、资源类别下同理进行划分。最后记得将已经完成的项目,放入归档中。\u003c/p\u003e","title":"文献一团乱麻?试试PARA管理方法"},{"content":"以前还在玩QQ空间时,曾流行过一阵点名风潮。也不知最早是从何处兴起,点名者会罗列出一系列诸如姓名、生日、谁传给你的、未来想做什么这样的问题,写上自己的答案并@一些朋友们,被点者要复制这些问题,填上自己的回复,再重复这一过程。上次见到这种玩法估计得是十五六年前了,历史竟能如此相像?\n再说回来,感谢Dayu的邀请,这也让我停更了一年多的博客重新出现了些生机。好久没写,Hugo的语法都有了不少更新,以至于和之前的主题不太兼容。为了能继续用之前的主题,还给它提了issue,研究了半天才给修好。\n1. 简单介绍下自己或者你的博客? 如果你和我不太熟,可以叫我Yorkson。这些年来,我的名字少说还有十来种不同的叫法,甚至到了看到对应的叫法就能判断是哪个时期的哪些朋友们的地步。目前我还在生物信息学专业读博,因此博客中主要的文章主要和一些生信分析、或是数据可视化(我的兴趣之一)有关。有很多杂七杂八的爱好,每天高强度上网冲浪,但很多内容不便在此展开,虽然是 i 人但更推崇线下面对面的交流。\n2. 什么契机让你开始写博客? 早在大学时就曾弄了自己的博客,甚至为域名去折腾了半天备案,后来发现花在折腾建立起博客上的时间远多于写东西的时间。最近的一次开始于22年上海疫情封控期间,被关在家里无事可做,于是尝试开始在少数派上写文章,也因此为契机能认识Dayu。后来为了能把一些杂七杂八的主题和零散的文章规整在一起,于是又一次买了域名弄了博客。另一方面的原因,则是因为这几年生信基本全靠自学,需要高强度上网检索各种奇怪问题,其中许多疑难杂症都是靠着世界另一处不认识的网友在博客等处写的文章解决的。这种「写下的东西能在未来某一天帮助素不相识之人」的感觉异常有趣,因此我希望能够以博客的形式分享知识,兴许能微微降低知识传播的门槛,生产出一些比AIGC质量稍高一点的内容。\n3. 你是如何完成创作的? 哎,这个问题大抵是问写作的工作流。我可能会偶然间想到某个选题,将其记录下来,偶尔有什么点子就稍微往里补充一下。过了一阵子想写文章了,就在那期间高强度围绕这个选题进行一定的检索,或是写一些片段,并尽量以某个逻辑组织起来,然后觉得还差点意思,就丢在那不管了。直到某个时候,感觉写出来的东西没必要也无法做到完全完美,这才会发出来。还有些想整理成文章的是这些年各种摸爬滚打所记录下的笔记,但是一直拖着没有写,可能将来的某天会整理出来吧。\n4. 运营博客的过程中是否有失去过动力?如果有,是为什么恢复的? 那可太有了,一旦停下就会停好久,不然也不至于一年半不写新东西。我觉得问题不大,至少我定期会有写作的愿望,过一阵又会犯懒不想写,尤其是忙的时候。不想写就不写,想写就写,就这么简单!不过这次大概是Dayu邀请我填这个点名才会继续更新一阵子吧,LOL。\n5. 如何搭建博客,以及运营博客每年需要投入的资金? 之前是买了国内的服务器,做了域名备案放在上面,但众所周知会有奇怪的麻烦之处。现在直接用Hugo生成静态网站,挂在GitHub Page里,体验也没差,成本也只有域名所需的一年那几十块钱。GitHub页面在某些时空访问可能费点劲儿,但大家都是天天上网冲浪的人,这点问题应该是会有办法的。\n6. 推荐 1 篇你博客中的文章,并推荐一个你喜欢读的博客,聊聊原因。 我会推荐这篇论文可视化配色简易指南,是我根据自己感兴趣的选题去整理出来的,我觉得会比较实用。最初发在少数派上,但因为一些图片懒得重新做从中删去了一部分,这里的是我写这篇文章的原始版本。要推荐一个博客,我会推荐虹线的博客,虽然部分文章可能会有人喜欢有人讨厌,但他的好几篇长文我读下来还是很喜欢并受到了不少启发的。\n7. 推荐 1 个近期喜欢的事物? 推荐个最近刚买的书签管理工具,Anybox,几乎完美满足了我的书签管理要求,终于摆脱了缓慢的Raindrop,原因我也刚写了文章细说了一下,见从Raindrop迁移到了Anybox。\n8. 想做还没有做的事,或想尝试还没有尝试的主题? 作为一个有八百个兴趣的人,想做的事太多了,除去已经尝试过然后搁置的那些,大概近期反复想起的是学不同的语言或是想学画画吧,都是需要很多时间精力投入才能有所回报的爱好,现在越来越没耐心长时间地集中注意力了,这可不行。\n9. 写到这里,闭上你的眼睛,深呼吸几分钟,或是出去溜达一圈,然后回来写任何你想写的东西。 好久不看书,这两天又拿出Kindle,发现集中注意力越来越困难了,让人分心的东西实在太多,这不太行。读书的过程让我有种安心的感觉,似乎是其他活动给不了的。但这几年似乎总在翻来覆去读之前已经看过的书,哪怕已经看了很多遍了。想要一些新鲜的,有意思的阅读内容。假如你已经读到了这里,不妨听我一个请求:如果让你只推荐一本书,你会推荐什么呀,请一定要告诉我!\n写在最后 一鼓作气写完了这篇点名,似乎真有种和素未谋面的人交流的感受,不知道会有多少人能看到这篇文章呢?假如有些错别字还请谅解,应该会有的。\n不论如何,如果你看到了这儿,向你问好!\n","permalink":"https://yorks0n.github.io/posts/nine_questions/","summary":"历史真是个圈。","title":"点名的风还是吹到了Blog"},{"content":"长期以来,我一直使用Raindrop作为我的书签管理服务,苦raindrop久矣。从2017年左右,一直用着免费版本的Raindrop,主要因为它那些付费版本的功能我也不太用得上,这些年也在其中积累下来大几百个书签,其中不少还标注了标签和备注方便查找。它倒是也能用,既支持多平台同步,又有网页版,最初免费版不支持创建嵌套的文件夹,后来也支持了,可以说功能上没啥大毛病。\n然而这几年里,总想找机会把它换掉,无他,Raindrop的性能真是太差了。不仅各个平台的App都宛如网页版套壳,各种操作的响应也都非常慢。每次想添加新书签,还要在添加页面等一会儿,确定它同步完了再关闭窗口;搜索的时候,也经常弹不出搜索结果。为此,我一直在尝试各种书签管理工具,想找个满意的替代品,大致需求也不复杂:\n性能良好,添加书签时的反应迅速 同时支持文件夹和标签两种分类方式,便于分大类和进行筛选 检索性能优秀 支持同步功能,需要至少有桌面与手机平台 最好能有独立App,而非依靠浏览器插件等形式实现 非订阅制,开源或可以买断 然而找了好久都没遇到合适的,许多开源项目都没有多端,或是同步起来相当费劲,亦或是书签多了后管理不便。一些付费服务页面fancy,但是性能巨差,或是性能好并且拥抱AI,于是每个月订阅费用感人。我还是希望能将书签管理与稍后读等内容管理分开的,避免混在一起检索起来麻烦,因此那些对内容的快速AI检索我也用不上。\n前几年,也曾多次按月订阅试过Anybox,但最初不支持文件夹,支持Tag但不能手动调顺序,以至按类别检索效率略低。后来虽然更新出了标签嵌套,但截至目前还是不支持手动调整标签顺序,没法像文件夹那样方便。不过在最近的尝试中发现它支持了文件夹,甚至可以直接把Raindrop导出中的文件夹结构保留,解决了我主要的痛点。虽然软件为订阅制,但支持198元永久版买断,总比按月支出来得舒服。于是在又订阅了一个月把书签都导进来试用几天后,果断买断了,删除Raindrop,使用至今非常舒适。不管是软件本身提供的快速检索栏,还是结合了Raycast的插件,都异常丝滑,好好好!\n甚至现在Anybox还可以将网页版归档下载下来保存,也许之后会把读过想储存的文章也迁移过来?\n要说Anybox现在的缺点,估计就是没有网页版也不支持win吧,但我日常主要用Mac和iOS,倒也完全够用。\n","permalink":"https://yorks0n.github.io/posts/change_to_anybox/","summary":"苦raindrop久矣,终于找到趁手的书签管理工具了","title":"从Raindrop迁移到了Anybox"},{"content":"前言 本文旨在介绍可视化作图过程中使用的基本元素,简单分析不同数据类型适合使用何种图形进行展示。通过了解这些基本元素,我们可以实现以下两个目的:\n更好地解读图片传递的信息 判断图表质量的好坏 在理解了基本元素的基础上,我们能够更好地设计图表,从而更高效直观地向读者传递我们的结论。\n用于数据可视化的基本图形元素 Marks and Channels 一张数据可视化图(特指将数据用图的形式展示出来)中的元素,基本可以分成下面提到的两大类。即使是较为复杂的图,也能拆分成诸多基本元素的组合。\n其中第一类称为 Mark(标记),是一张图中的基本图形元素。 Mark根据其维度可以细分为三种:\n第二类元素是 Channel(通道),指用于控制 Mark 如何呈现在图中的变量。 通道可以分为以下几种:\n位置 颜色 形状 斜率 大小(长度、面积、体积) 这样讲非常抽象,来几个具体的例子:\na 图,使用线段作为 Mark(柱状图就是些粗了点的线段),Channel 是长度,所以当我们在看柱状图时,比较的实际是不同线段(柱子)的长度 b 图,用点作为 Mark,Channel 是点在图上的位置,每个点都有其坐标 (x,y) c 图,在 b 图的基础上,增加了一个颜色 Channel,用这个通道将点分成了红蓝两组 d 图,在 c 图的基础上,又增加了面积作为 Channel 控制点的大小,额外编码了一个变量 以此可见,无论复杂还是简单的图,都是通过 Marks 与 Channels 的适当组合得到的。\nChannel Rankings 在画图的时候,一次必然不会用到全部的上述元素。由于各种 Channel 传递信息的效果并不一致,要想让你的图更为直观,需要选择恰当的元素表现方式。\n下图展示了不同类型的数据,用不同 Channel 进行表达时,其效果的优劣,越靠上的 Channel 越便于读者理解。\n有顺序的数据(比如一组有大有小的测量值)应当以左边这组形式呈现,类别数据(比如野生型和突变体这两组材料)应当以右边的形式呈现。\n对于两类数据,效果最好的都是空间位置。我们来看一组例子,体会一下不同数值编码方式传递信息的效率差异。\n浏览下面的每一张图,快速判断图中的数据能分为几组。\n第一的图,用位置+颜色编码,很容易将点进行分组。 第二张图,用大小+颜色编码,稍微混乱了一些,但还算可以分辨。 第三张图,该分成三组还是四组?这张图采用宽度+高度编码,还算可以分辨,但由于我们通常感知面积快于形状,所以矮宽/高瘦的椭圆形可能在直觉上会被归为一组,于是图中四组容易被认作大中小的三组。 第四张图,只用颜色进行编码,非常混乱,实际也是四组。 不同数据类型与其适合的展示方式 One quantitative value 首先是一维数据,只有一组连续值,我们希望展示这组数据的分布情况。如果只用平均值、标准差来描述,可能会损失很多信息,便可以考虑用直方图或密度图来展示。\n直方图(Histogram) 直方图(Histogram)是展示 连续数据分布情况 最常用的工具,它划分好一组区间,将落到每个区间中值的个数进行统计并绘图,使用线条的长度来编码数据。由于直方图需要对连续型数据做离散分组,因此它有一个明显的缺点,就是它的形状依赖于分组的端点,例如若有好几个相同的数值正好处在分组端点上,那么我们只要稍微向左或向右移动一下分组端点,这些数据点就会被划分入不同的区间,导致矩形条的高度变化。\nMark: line Channel: length 密度图(Density plot) 密度图利用核密度估计,对原始数据估计其密度函数,相比直方图对数据的描述更加准确。然而其边界处可能由于边界效应与实际情况不符。\nMark: line Channel: position Two quantitative values 当面对二维连续值的情况,比一维稍微复杂一点,可以用散点图展示它们之间的关系。\n散点图(Scatter plot) 散点图展示 两个变量之间的关系 ,这种关系可能是线性或非线性的。图中每一个点的横纵坐标都分别对应两个变量各自的观测值,因此散点所反映出来的趋势也就是两个变量之间的关系。\nMark: point Channel: position One key, one value 假如一张表是这样的:\n能够定位到某个表格位置的变量称作 Key,这通常是我们统计对象的某个属性,比如某个材料的名称; 表格中某个格中具体的值被称为 Value 柱状图(Bar chart) 柱状图可能是我们最熟悉的图形之一,目前是各种统计图形中应用最广泛的,但柱状图使用统计后的数据(平均值、标准差)进行作图,所能展示的统计量比较贫乏:只能以矩形条的长度展示原始数值,对数据的分布几乎没有任何展示。\n比如在下图中,因为展示的是每个动物的平均质量,如果不加误差线,我们既不能看出它的变异程度,也看不到这些数据的分布。\nMark: lines Channel: position, length 箱线图(Box plot) 统计(平均值、标准差)后画出的柱状图损失了太多信息,相比之下,直接用原始数据画出的箱线图呈现了 更详细的数据分布情况 ,并允许数据中包含异常值。\nMark: line, point Channel: position, length 小提琴图(Violin plot) 小提琴图是密度曲线图的变体,有时也与箱线图一同呈现,能够更清晰地展示数据的分布情况。由于其外形与小提琴的形状相似(尤其展示双峰数据时),所以称为小提琴图。通常要较多的数据量,才能呈现出比较好看的小提琴图。\nMark: line, point Channel: position, length One ordered key, one value 当我们的数据,其中的 Key 有内在顺序时,其呈现方式又可以有所不同。\n折线图(Line chart) 比方说展示一组随时间(比如年份)变化的数据,一般会用折线图的形式,更容易体现出数据的变化趋势。\nMark: line, point Channel: position 各种常见的基本图片类型就讲到这,我在每张图处都表明了作图利用到的 Mark 与 Channel。比较后就会发现,各种图确实都可以抽象为作图元素的适当组合。\n常见问题 以下介绍一些常见的问题与争议,同时包含一些注意事项。篇幅有限,没法将各种问题逐一分析,如果感兴趣也可以与我深入进行交流。\n选择柱状图还是折线图 这个问题一般取决于数据的类型,尤其是其中 Key 的类型。\n如果是类别数据,用柱状图 如果是有序数据,用折线图 需注意,类别数据不应使用折线图来展示,而有序数据也能用柱状图表示。\n下面两张图展示了性别与身高的关系,在这里 Key 为性别,属于类别数据,因此柱状图可以,但是折线图不合适。因为折线图天生带有一种展示趋势的倾向,会错误地传递出一种「从 Female 到 Male 身高存在上升趋势」,但一般来说性别不会逐渐变化,通常也不会出现身高随着性别变化而改变的情况。\n再看下面的图,年龄与身高的关系。柱状图展示了不同年龄段的身高差别,折线图展示出从十岁到十二岁儿童身高有上升的趋势,这就非常合理了。\n原点是否从0开始 一个作图过程中需要注意的问题:原点是否从0开始?在不同图中这个问题存在一些争议,但是 在柱状图中,原点一定要从0开始。 我们有时也会见到,为了刻意传递出某种结论而在柱状图中不从零开始展示数据的情况。\n回想一下前面提到柱状图的时候,我们提到柱状图利用长度来编码数值。正因如此,长度需要与数值以合适的比例关系进行对应,100 是 50 的两倍,因此在线性坐标轴上,对应 100 的柱子长度就该是 50 的两倍长。\n而折线图利用位置来编码数值,所以在一些情况下,为了展示出更清晰的局部变化,可以不从0开始。\n雷达图与饼图 雷达图实际上是极坐标系中的折线图,以到中心的距离编码数值,然而其可读性非常差,绝大多数情况下避免使用。\n纵坐标对应的数值不易阅读 折线的趋势变化不明显 折线图不应用来表示没有顺序的分组数据 除非周期性数据,否则一组数据结尾和开始处的连接没有实际含义 饼图用角度编码数值,给人的感知是角度/面积,可读性也不好。因为人眼对角度或面积辨识能力不强,尤其是相似的角度非常多的时候。\n回看一下最开始放的排序图,角度与面积都排在了最后,因此请谨慎使用饼图。如果用,对数据进行排序后再画饼图,可以稍稍让读图变得轻松一点。\n一些奇怪的图 我翻了一些CNS文章,除了热图和树状/网状图,基本都是上面提到的图片类型。其中有些变体形式的图也非常不错,比如下面这张直接展示出原始值及其平均值,又省空间又直观。\n或是下面这种(我画了个示意图),相比于柱状图省去了柱子的部分,同样呈现出平均值和误差线,又比柱状图省下不少空间(柱状图的柱子宽度几乎毫无意义)。\n再举个例子,说说如何用图片元素的基本知识,帮助我们读一张图,尤其是如今日益花哨的各种组学图。下面是张呈现出转录组数据的火山图(Volcano plot),一眼看上去还挺炫,让我将其中的各种元素拆分一下:\n横坐标与纵坐标都是取 log 后的连续型数值,坐标轴不包括离散(分组)数据,因此这是将(x,y)映射到位置的散点图,每个点代表一个基因 再看横纵坐标表示的含意,横坐标是 R-NR 数据的比值,因此越靠右表明比值越大,越靠左则比值越小 图中的两条曲线划定了一定范围,因此作为比较数据的阈值 数据点还映射到了不同的颜色,灰色是没有达到阈值的数据,黑色点达到阈值,其中又有些选出的基因,被标注以不同颜色,应该是依照某个其他因素进行了分组 那么,再接下去看看上下文有没有提到这些颜色代表了什么分组,就清楚它是要讲什么了。\n好了,这篇文章就写到这,我们下次再见。\n参考资料与延伸阅读 Data Visualization - A practical introduction Visualization Analysis \u0026amp; Design ","permalink":"https://yorks0n.github.io/posts/basic_elements_data_vis/","summary":"介绍可视化作图过程中使用的基本元素,简单分析不同数据类型与适合使用的展示方式。","title":"数据可视化——基本图形元素及其应用"},{"content":"异常值? 首先,什么是异常值,某个特别的值真的是异常值吗?\n在统计学中,异常值(outlier)是与其他观察值显著不同的数据点。它们可能来源于测量方法的变异性,可能指示出新的数据情况,或者也可能是实验误差的产物。然而,判断某个值是否为异常值并不轻松,也没有一劳永逸的方法或是唯一可信的标准,因此这里整理几种常见的单变量异常值检测方法,以供自己或他人将来参考。\n至于如何处理异常值,是原样保留还是剔除它们,往往会随着分析目的等因素发生变化,但请一定三思,avoid cherry-picking。\n异常值检测 three-sigma rule 首先计算数据的平均值mu,与标准差std\nthree-sigma 法则将任何 $abs(x - µ) \u0026gt; 3 * std$ 的值作为异常值,这里的3也可以根据情况进行调整\n这种方式与另一种Z-score方法实际是一致的:对数据进行Z-score变换,就是在计算数据的Z统计量\n$$ z = (x-µ)/σ $$\n对应于three-sigma方法中,就是这里的 $abs(z) \u0026gt; 3$会被视为异常值。\n这里划定异常值的系数取3,实际已经是一个非常极端的值了,我们假设Z-score变换后的数据符合标准正态分布,此时置信区间内的概率$p(|z| \u0026gt; 3) = 0.9973$,即数据落在这个区间外的概率只有0.0027。\n我们假设随机来一组数据:\nset.seed(2501) # 生成一组10个符合正态分布的随机数,µ = 100,σ = 10 random_numbers_1 \u0026lt;- round(rnorm(10, mean = 100, sd = 10)) # 99 104 103 91 106 100 96 90 110 99 # 再添加几个值,分别为68,220 data_1 \u0026lt;- c(random_numbers_1, 68, 220) # 99 104 103 91 106 100 96 90 110 99 68 220 此时样本均值和标准差分别为\nmu_1 = mean(data_1) # 107.17 sigma_1 = sd(data_1) # 37.13 此时 three-sigma的区间为$mu \\pm 3*sigma = (-4.23, 218.57)$,是个大到离谱的区间了。上面的数据中只有220会被这个方式定义为异常值。这个范围对应初始的 $N(100,10^2)$ 中的概率为 $1 - 9.7^{-26}$,即有真实值落在区间外的概率为$9.7^{-26}$,因此是一个区间范围非常大,非常宽松的方法。其原因一方面是选择 3 作为系数,因此可以视情况将其调整为其他值,比如 2.5 等。\n但是,计算置信区间的方式相对比较繁琐,一种更直观的是对所有数据直接计算 z 统计量\n$$ |z| = \\left|\\frac{X - \\bar{X}}{s}\\right| $$\nabs(round(scale(data_1)[,1],2)) # 0.22 0.09 0.11 0.44 0.03 0.19 0.30 0.46 0.08 0.22 1.05 3.04 其中68的z变量为1.05,220的z变量为3.04,如果以3为标准就可以将其作为异常值。\n另一方面,该方法本身涉及到计算平均值和标准偏差,这两个值都受异常值影响很大,尤其是标准偏差,假设上面额外增加的 220 改成 200,这种方法的区间就会成为 $(10.54, 200.45)$,这时 200 落在了边界附近,却刚好不会被视为异常值。\nIQR 方法 有时也称为箱线图方法,通过计算数据的分位数判断异常值,大概方式如下\nQ25 = 25th_percentile Q75 = 75th_percentile IQR = Q75 - Q25 // inter-quartile range IF (x \u0026lt; Q25 - 1.5*IQR) OR (Q75 + 1.5*IQR \u0026lt; x) THEN x is a mild outlier IF (x \u0026lt; Q25 - 3.0*IQR) OR (Q75 + 3.0*IQR \u0026lt; x) THEN x is an extreme outlier IQR 方法的好处在于,去掉异常值前后,其他值的中位数和 IQR 基本是不变的。\n同样用上面的数据,计算一下这种方式的区间:\nquantile(data_1, probs = c(0.25,0.75)) # Q25 = 94.75 # Q75 = 104.50 # IQR = 9.75 此时1.5倍IQR的区间为,相对还是个比较窄的范围,后添加进去的 68 和 220 在此情况下都会被视为异常值。\n$$ (Q25-1.5\\cdot IQR, Q75+1.5\\cdot IQR) = (80.12, 119.12) $$\n3 倍 IQR 的范围则为 $(65.5, 133.75)$ 相对会宽一些,此时只有220会被作为异常值。\n$$ (Q25-3\\cdot IQR, Q75+3\\cdot IQR) = (65.5, 133.75) $$\n这种方式的一个好处就是分位数对异常值不太敏感,如果把220变为200,这个区间依然是不会变的。\n1.5 倍 IQR 的区间$(80.12, 119.12)$放到原始的分布中去大致对应于概率 95% 的正态区间;3 倍 IQR 的区间对应 99.94% 的概率,真实值落入这个区间外的概率也足够低了;当然相比于 three-sigma,还是严格了一些。\n因此,IQR 方法更容易检测出异常值,当然也更有可能把真实值视为异常值,因此需要谨慎选择 IQR 区间的倍数。\n中位数绝对偏差 MAD 上面的方法可能会遇到一些问题,包括\n均值和标准差的计算依赖于所有数值,因此离群值可能会对均值和标准差产生较大影响 three-sigma、IQR等方法对于小样本不一定合适(? 还有另一种可以衡量变异程度的统计量,中位数绝对偏差(Median absolute deviation,MAD)\n其计算也相当简便:\n对于一组数据$X_1, X_2, X_3, \u0026hellip;, X_n$ ,其中位数为$\\tilde{X} = median(X)$\nMAD是各个数据与其中位数绝对偏差的中位数:\n$$ MAD = median(|X_i - \\tilde{X}|) $$\nMAD 相比方差更能适应数据集中的异常值:在标准偏差中,与均值的距离是平方的,因此大偏差的权重更大,因此离群值会严重影响它;在 MAD 中,由于中位数天生受异常值影响较小,少数异常值的偏差几乎不影响MAD。\n上面 three-sigma 使用标准方差 σ 衡量变异程度,IQR 方法使用 IQR 衡量变异,类似的,在这里使用 MAD 衡量数据的变异幅度。MAD 的使用方式类似Z-score变换中将表标准差应用于平均值的过程,为了将 MAD 作为与标准偏差 σ 一致的估计量,需要有\n$$ \\hat{\\sigma} = k \\cdot MAD $$\n其中 k 是一个比例系数,取决于分布。对于正态分布的数据,k 被认为是\n$$ k = 1/\\Phi^{-1}(3/4) \\approx 1.4826 $$\n即标准正态分布$Z = (X-\\mu)/\\sigma$的分位数函数$\\Phi^{-1}$(也称累积分布函数,R中计算使用 qnorm)的倒数。\n用一开始的数据计算\n# 99 104 103 91 106 100 96 90 110 99 68 220 mad_1 \u0026lt;- median(abs(data_1 - median(data_1))) # mad_1 = 5.5 round(abs((data_1 - median(data_1)) / (mad_1*1.4826)), 2) 0.06 0.55 0.43 1.04 0.80 0.06 0.43 1.17 1.29 0.06 3.86 14.78 类似,视情况选择合适的值作为阈值,即可检出异常值。如果选择 3,对应的区间为 (75.04, 123.96),概率范围为98.5%;如果选择 4,对应的区间为 (58.73, 140.27),概率范围为99.89%。\nk 的推导过程如下\n为了使 $\\pm k*MAD$ 的区间落在概率为 $p_0$ 的标准正态分布中区间内,有以下公式\n$$ p_0 = P(|X - µ| \\le k \\cdot MAD) = P\\left( \\left|\\frac{X - µ}{σ}\\right| \\le \\frac{k \\cdot MAD}{σ}\\right) = P\\left( |Z| \\le \\frac{k \\cdot MAD}{σ} \\right) $$\n因此就有\n$$ \\Phi(k \\cdot MAD/\\sigma) - \\Phi(-k \\cdot MAD/\\sigma) = p_0 $$\n又因为\n$$ \\Phi(-k\\cdot MAD/\\sigma)=1-\\Phi(k \\cdot MAD/\\sigma) $$\n所以\n$$ \\Phi(k \\cdot MAD/\\sigma)= \\frac{1 + p_0}{2} $$\n令 $p_0 = 0.5$,即 50% 正态分布区间时,\n$$ k = \\frac{\\sigma}{MAD} = \\frac{1}{\\Phi^{-1}(3/4)} \\approx 1.4826 $$\n这里选择 0.5 是因为,对于均值为零的对称分布,总体 MAD 是分布的第 75 个百分位数,因此标准正态分布的总体 MAD 刚好等于$\\Phi^{-1}(3/4)$。\n参考资料 Recommended anomaly detection technique for simple, one-dimensional scenario?\n5 Ways to Detect Outliers/Anomalies That Every Data Scientist Should Know Median absolute deviation\n","permalink":"https://yorks0n.github.io/posts/outlier_detection/outlier_detection/","summary":"整理一下检测单变量异常值的方法。","title":"单变量异常值检测方法"},{"content":"前几天看到群里有人问如何画一张类似下图的、带拟合线与误差的相关性图,这里找点数据来演示一下怎么画。\n找了点数字画了个例子,假设数据读进来是这样的两列:\n绘图的部分我用了这些\nleg \u0026lt;- theme(title=element_text(size=15), axis.text.x=element_text(size=14), axis.text.y=element_text(size=14), legend.text=element_text(size=14)) label_text \u0026lt;- paste0(\u0026#34;r = \u0026#34;, round(cor(subdata$Na,subdata$K),2)) library(ggplot2) ggplot(subdata, aes(x = log(Na), y = log(K))) + geom_point(size = 2,color = \u0026#34;#31705a\u0026#34;) + stat_smooth(method = \u0026#34;lm\u0026#34;, color = \u0026#34;#31705a\u0026#34;)+ theme_classic() + annotate(\u0026#34;text\u0026#34;, x=5.8, y=9, label= label_text) + leg 以上代码画出来的图如下: 其中各部分的解释如下\nleg \u0026lt;- theme(title=element_text(size=15), axis.text.x=element_text(size=14), axis.text.y=element_text(size=14), legend.text=element_text(size=14)) # 用于指定字体大小等,可以先忽略 label_text \u0026lt;- paste0(\u0026#34;r = \u0026#34;, round(cor(subdata$Na,subdata$K),2)) # 用于计算相关系数r的值,并处理成标在图上的「r = xxx」的文本 library(ggplot2) # 用ggplot2包画图 ggplot(subdata, aes(x = log(Na), y = log(K))) + #指定画图的数据subdata,在aes(x = ,y = )中指定横纵坐标轴 geom_point(size = 2,color = \u0026#34;#31705a\u0026#34;) + #绘制散点部分,点的大小为2,颜色为浅绿色 stat_smooth(method = \u0026#34;lm\u0026#34;, color = \u0026#34;#31705a\u0026#34;)+ #绘制拟合线部分,method = \u0026#34;lm\u0026#34; 使用线性拟合,颜色同前 theme_classic() + # 使用ggplot的classic画图主题,是个只显示横纵坐标轴的主题 annotate(\u0026#34;text\u0026#34;, x=5.8, y=9, label= label_text) + # 添加上文字标注,类型是\u0026#34;text\u0026#34;,位置在x=5.8,y=9 leg # 添加之前指定的字体大小部分,不关键 ","permalink":"https://yorks0n.github.io/posts/corplot_case/","summary":"\u003cp\u003e前几天看到群里有人问如何画一张类似下图的、带拟合线与误差的相关性图,这里找点数据来演示一下怎么画。\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"images/corplot1.png\" alt=\"demo\" /\u003e\n\n找了点数字画了个例子,假设数据读进来是这样的两列:\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"images/corplot2.png\" alt=\"Untitled\" /\u003e\n\u003c/p\u003e\n\u003cp\u003e绘图的部分我用了这些\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-r\" data-lang=\"r\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eleg \u003cspan style=\"color:#f92672\"\u003e\u0026lt;-\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003etheme\u003c/span\u003e(title\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#a6e22e\"\u003eelement_text\u003c/span\u003e(size\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#ae81ff\"\u003e15\u003c/span\u003e), \n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e axis.text.x\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#a6e22e\"\u003eelement_text\u003c/span\u003e(size\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#ae81ff\"\u003e14\u003c/span\u003e),\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e axis.text.y\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#a6e22e\"\u003eelement_text\u003c/span\u003e(size\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#ae81ff\"\u003e14\u003c/span\u003e),\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e legend.text\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#a6e22e\"\u003eelement_text\u003c/span\u003e(size\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#ae81ff\"\u003e14\u003c/span\u003e))\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003elabel_text \u003cspan style=\"color:#f92672\"\u003e\u0026lt;-\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003epaste0\u003c/span\u003e(\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;r = \u0026#34;\u003c/span\u003e, \u003cspan style=\"color:#a6e22e\"\u003eround\u003c/span\u003e(\u003cspan style=\"color:#a6e22e\"\u003ecor\u003c/span\u003e(subdata\u003cspan style=\"color:#f92672\"\u003e$\u003c/span\u003eNa,subdata\u003cspan style=\"color:#f92672\"\u003e$\u003c/span\u003eK),\u003cspan style=\"color:#ae81ff\"\u003e2\u003c/span\u003e))\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003elibrary\u003c/span\u003e(ggplot2)\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003eggplot\u003c/span\u003e(subdata, \u003cspan style=\"color:#a6e22e\"\u003eaes\u003c/span\u003e(x \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003elog\u003c/span\u003e(Na), y \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003elog\u003c/span\u003e(K))) \u003cspan style=\"color:#f92672\"\u003e+\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e \u003cspan style=\"color:#a6e22e\"\u003egeom_point\u003c/span\u003e(size \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#ae81ff\"\u003e2\u003c/span\u003e,color \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;#31705a\u0026#34;\u003c/span\u003e) \u003cspan style=\"color:#f92672\"\u003e+\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e \u003cspan style=\"color:#a6e22e\"\u003estat_smooth\u003c/span\u003e(method \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;lm\u0026#34;\u003c/span\u003e, color \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;#31705a\u0026#34;\u003c/span\u003e)\u003cspan style=\"color:#f92672\"\u003e+\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e \u003cspan style=\"color:#a6e22e\"\u003etheme_classic\u003c/span\u003e() \u003cspan style=\"color:#f92672\"\u003e+\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e \u003cspan style=\"color:#a6e22e\"\u003eannotate\u003c/span\u003e(\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;text\u0026#34;\u003c/span\u003e, x\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#ae81ff\"\u003e5.8\u003c/span\u003e, y\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#ae81ff\"\u003e9\u003c/span\u003e, label\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e label_text) \u003cspan style=\"color:#f92672\"\u003e+\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e leg\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e以上代码画出来的图如下:\n\u003cimg loading=\"lazy\" src=\"images/corplot3.png\" alt=\"Untitled\" /\u003e\n\u003c/p\u003e\n\u003cp\u003e其中各部分的解释如下\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-r\" data-lang=\"r\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eleg \u003cspan style=\"color:#f92672\"\u003e\u0026lt;-\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003etheme\u003c/span\u003e(title\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#a6e22e\"\u003eelement_text\u003c/span\u003e(size\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#ae81ff\"\u003e15\u003c/span\u003e), \n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e axis.text.x\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#a6e22e\"\u003eelement_text\u003c/span\u003e(size\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#ae81ff\"\u003e14\u003c/span\u003e),\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e axis.text.y\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#a6e22e\"\u003eelement_text\u003c/span\u003e(size\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#ae81ff\"\u003e14\u003c/span\u003e),\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e legend.text\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#a6e22e\"\u003eelement_text\u003c/span\u003e(size\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#ae81ff\"\u003e14\u003c/span\u003e)) \u003cspan style=\"color:#75715e\"\u003e# 用于指定字体大小等,可以先忽略\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003elabel_text \u003cspan style=\"color:#f92672\"\u003e\u0026lt;-\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003epaste0\u003c/span\u003e(\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;r = \u0026#34;\u003c/span\u003e, \u003cspan style=\"color:#a6e22e\"\u003eround\u003c/span\u003e(\u003cspan style=\"color:#a6e22e\"\u003ecor\u003c/span\u003e(subdata\u003cspan style=\"color:#f92672\"\u003e$\u003c/span\u003eNa,subdata\u003cspan style=\"color:#f92672\"\u003e$\u003c/span\u003eK),\u003cspan style=\"color:#ae81ff\"\u003e2\u003c/span\u003e)) \u003cspan style=\"color:#75715e\"\u003e# 用于计算相关系数r的值,并处理成标在图上的「r = xxx」的文本\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003elibrary\u003c/span\u003e(ggplot2) \u003cspan style=\"color:#75715e\"\u003e# 用ggplot2包画图\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003eggplot\u003c/span\u003e(subdata, \u003cspan style=\"color:#a6e22e\"\u003eaes\u003c/span\u003e(x \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003elog\u003c/span\u003e(Na), y \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003elog\u003c/span\u003e(K))) \u003cspan style=\"color:#f92672\"\u003e+\u003c/span\u003e \u003cspan style=\"color:#75715e\"\u003e#指定画图的数据subdata,在aes(x = ,y = )中指定横纵坐标轴\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e \u003cspan style=\"color:#a6e22e\"\u003egeom_point\u003c/span\u003e(size \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#ae81ff\"\u003e2\u003c/span\u003e,color \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;#31705a\u0026#34;\u003c/span\u003e) \u003cspan style=\"color:#f92672\"\u003e+\u003c/span\u003e \u003cspan style=\"color:#75715e\"\u003e#绘制散点部分,点的大小为2,颜色为浅绿色\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e \u003cspan style=\"color:#a6e22e\"\u003estat_smooth\u003c/span\u003e(method \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;lm\u0026#34;\u003c/span\u003e, color \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;#31705a\u0026#34;\u003c/span\u003e)\u003cspan style=\"color:#f92672\"\u003e+\u003c/span\u003e \u003cspan style=\"color:#75715e\"\u003e#绘制拟合线部分,method = \u0026#34;lm\u0026#34; 使用线性拟合,颜色同前\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e \u003cspan style=\"color:#a6e22e\"\u003etheme_classic\u003c/span\u003e() \u003cspan style=\"color:#f92672\"\u003e+\u003c/span\u003e \u003cspan style=\"color:#75715e\"\u003e# 使用ggplot的classic画图主题,是个只显示横纵坐标轴的主题\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e \u003cspan style=\"color:#a6e22e\"\u003eannotate\u003c/span\u003e(\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;text\u0026#34;\u003c/span\u003e, x\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#ae81ff\"\u003e5.8\u003c/span\u003e, y\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#ae81ff\"\u003e9\u003c/span\u003e, label\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e label_text) \u003cspan style=\"color:#f92672\"\u003e+\u003c/span\u003e \u003cspan style=\"color:#75715e\"\u003e# 添加上文字标注,类型是\u0026#34;text\u0026#34;,位置在x=5.8,y=9\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e leg \u003cspan style=\"color:#75715e\"\u003e# 添加之前指定的字体大小部分,不关键\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"复现一张相关性图"},{"content":"Best practices for single-cell analysis across modalities 跨模式单细胞分析的最佳实践,于 2023 年 3 月 31 日发表于 nature reviews genetics。最近在研究单细胞分析相关的资料,因此记下这篇笔记。文章中包含了 Transcriptome、Chromatin accessibility、Surface protein expression、空间转录组等多个方面,但就近期关注点而言,只精简记录单细胞转录组部分的笔记。如果有需要,可以阅读原文。\n从原始计数矩阵到高质量单细胞数据 原始计数矩阵是直接从测序数据定量得来的矩阵,一般根据每个细胞 barcode 与 UMI 确定细胞中各种 mRNA 的数量,然而原始数据中包含着各种系统噪声和误差(比如来自建库操作、样本质量、测序批次等),因此在这一预处理过程中试图去除误差。这一过程涉及到质量控制、归一化、数据矫正和特征选择等过程,还可能会涉及到消除批次效应以整合多批次数据的过程。\n滤低质量细胞和噪声校正 Filtering low-quality cells and noise correction 大多数分析过程假定每个单细胞液滴中都包含来自单个完整细胞的 RNA。细胞质量差(比如死细胞)、溶液中破裂细胞产生的 RNA 污染、同时捕获多个细胞的情况违反这一假设,因此需要在进一步分析之前去除这部分数据。\n低质量细胞:检测基因数量过少、深度过低或是线粒体计数(植物还有叶绿体)过多的细胞都被认为是低质量细胞。一般通过手动设置的阈值来进行识别和过滤,可以参照先前文章或是基于中值绝对偏差数对样本进行过滤。需要综合考虑过滤的指标,同时注意质量控制是在样本水平上进行的,因为样本之间的阈值可能会有很大差异。\n中值绝对偏差数(Median Absolute Deviation, MAD)\n基于中值绝对偏差数(Median Absolute Deviation, MAD)的样本自动过滤是一种统计方法,用于识别和剔除数据集中的离群值。这种方法主要有以下几个步骤:\n计算数据集的中位数(median)。 对每个数据点,计算其与中位数的偏差绝对值。 计算这些绝对偏差的中位数,得到MAD值。 选择一个阈值,通常是MAD的某个倍数(例如3倍MAD),用于判断数据点是否为离群值。 剔除大于阈值的数据点,即被认为是离群值的数据点。 这种基于MAD的方法对于处理非正态分布的数据集具有较好的鲁棒性,而且相对标准差受异常值影响更小,因此可以有效地识别和过滤异常值。\n无细胞游离 RNA:通常存在于溶液中,并在建库过程中分配给每个细胞,产生一种类似背景值的效果。如果是细胞类群特异性标志物的 RNA 污染了其他细胞,后续分析中可能将不同的细胞群混合在一起。流行的 SoupX 等方法根据样本中「空液滴」的表达情况去除污染;CellBender 将环境 RNA 的去除制定为无监督贝叶斯模型,该模型不需要细胞类型特异性基因表达谱的先验知识。应当尽量不忽略去除环境 RNA 这一步,以提升下游分析的质量。\n空液滴和双联体液滴(包含两个细胞的液滴):由不同细胞类型形成的双联体很难注释,并可能导致细胞类型标注错误。常见的双峰检测方法随机抽取两个细胞组合成模拟双联体,并将其与其他细胞测量结果进行比较。scDblFinder 采用此方法, 并在多项测试中准确性和计算效率优于其他方法。还可以应用多种不同检测方法并比较结果以提高准确性。\n归一化和方差稳定化 Normalization and variance stabilization 不同细胞的 mRNA 含量不同,加上测序过程随机误差,将导致细胞有不同的初始计数。归一化可以矫正测序深度的差异,使不同细胞具有可比性。随后稳定方差以确保少数离群值对整体数据影响不会太大。\nshifted logarithm transformation:使用缩放系数s的 log(𝑦/𝑠+1) 表现良好,但不应使用 CPM(counts per million)作为输入。\nshould not be used with counts per million as an input, as it reflects an unrealistically large overdispersion. 原文如此,但没看懂为什么,待补充。\n通过使用一个公因数缩放所有基因,会假定由于细胞大小导致的测序深度差异可以忽略不计。然而对于异质性较大的数据集,其中包含了特性不同的各种细胞,其本身基因表达差异就较大,难以对每个基因找到一个合适所有细胞的系数。\n此外还有 Scran 标准化和 Pearson 残差方法。shifted logarithm transformation 被证明可以更好地稳定方差以进行后续降维,Scran 在批量校正任务中表现良好,Pearson 残差更适合生物变异基因的选择和稀有细胞身份的识别。\n消除混杂的变异来源 Removing confounding sources of variation 混杂变异可以来源于技术和生物,并且应该分开处理。\n批次效应:多个样本的数据集可能会由于技术产生的批次效应,需要恰当的数据整合方法。canonical correlation analysis 与 Harmony 等线性嵌入模型在处理不同批次的简单整合上表现良好;在复杂任务重, atlas、scANVI、scVI、scGen等深度学习方法,及 Scanorama 等显性嵌入模型表现较好。scIB 包可用于使用上述基准的评估指标来评估整合效果。 生物因素:细胞周期等因素同样会引入误差,使得细胞间差异来源于细胞周期而非细胞类型。可以使用 Scanpy 或 Seurat 中内置的细胞周期标记与校正函数作为基础;Tricycle 等更复杂的方法对细胞异质性高的数据集表现良好。 选择信息特征和降维 Selecting informative features and reducing dimensionality 理想情况下,特征选择方法应优先选择在亚群间(而非亚群内)变化的基因,并且不影响亚群内更小亚群的可识别性。\n通过拟合基因模型获得 deviance 来识别信息量大的基因,模型假定所有细胞基因表达一致,然后检验哪些基因违反假设,从而选择基因。此外,按此方法利用了原始计数对基因进行排序,不依赖归一化,不会因为数值中零值过多产生误差(zero inflation)。选择特征后可以通过 PCA 等方式进一步降低数据集维度,同时 PCA 结果可以进一步作为输入应用 t-SNE、UMAP、PHATE 等可视化降维方法。注意,最近有研究表明,仅仅依靠2D嵌入可能会导致对细胞之间关系的错误解读。因此,结果不应仅基于对结果的视觉检查来制定,而应结合其他定量评估。\n为细胞集群确定亚群身份 From clusters to cell identities 从单个细胞到集群 From single cells to clusters 识别细胞群的第一步是将表达模式相似的细胞聚类成组,推荐使用 Leiden 算法进行聚类。\n为细胞集群确定细胞身份 Mapping cell clusters to cell identities 建议分三步进行:自动注释 → 手动注释 → 验证。\n自动注释:分为基于分类器的方法和基于参考数据集的映射方法。分类器可以参考 CellTypist 和 Clustifyr,两者利用先前注释过的数据集进行训练并参考大量基因进行分类;映射方法有 scArches、Symphony 或 Azimuth。这两类方法都依赖于参考数据的质量+模型质量+参考数据集对新数据的适用性。 手动注释:利用细胞群的特异性标志基因进行注释。 验证:需要仔细设计验证试验,并且对于复杂数据或稀有亚群,可能没有资料可供参考。 伪时间分析——从离散状态到连续过程 From discrete states to continuous processes 根据细胞表达模式的相似性,沿着轨迹对细胞进行排序的模型被称为轨迹推断或伪时间分析。这类分析的效果取决于数据集中存在的轨迹类型,Slingshot 对简单结构表现良好,PAGA 和 RaceID/StemID 对复杂结构表现更好,建议使用 dynguidelines 选择适用的方法。当预期结构未知时,应采用不同假设通过多种方法确认轨迹和假设。推断出的轨迹不一定有生物学意义。\n利用 RNA velocity (mRNA 剪切、未剪切、降解的比例),比如考虑模型剪接动力学的 velocyto 和 scVelo,可以根据未剪接和剪接片段确定 RNA velocity:如果一个基因被激活了,未剪切的 RNA 会先于剪切的 RNA 产生。获得的 RNA velocity 输入 CellRank 来估计细胞命运。\n谱系追踪根据细胞中观察到的变异(例如自然发生的基因突变)来推断其谱系模型,判断克隆群体中的细胞分裂历史,可以使用 Cassiopeia 提供的多种算法进行分析,建议对比多种算法的结果。同时还有能处理更加复杂谱系的 LineageOT 工具,以及追踪静态条形码的 CoSpar。\n揭示机制 Revealing mechanisms 对数据进行注释后,可选的分析变得多样,根据研究问题选择要进行的后续分析。\n差异基因表达分析 Differential gene expression analysis 目前单细胞的差异表达分析从两个思路进行:\n样本层面的方法:将单个样本中的多个细胞细胞读数合并,生成人工合成的批量样本,再利用常规的转录组差异表达分析工具,比如 edgeR、DESeq2 或是 limma。 细胞层面的方法:利用广义混合效应模型(比如 MAST),对单个细胞进行建模。 各个工具之间的一致性和稳健性较低,但相对而言,为常规 DEG 设计的工具表现良好,而单细胞特异性的方法通常会低估基因表达的变异程度,因此倾向于将高表达的基因错误标记为差异表达基因。因此推荐 limma、edgeR 或 DESeq2。\n基因集富集分析 Gene set enrichment analysis 常见的数据库包括 MSigDB、Gene Ontology、KEGG 与 Reactome 等,此外还有用于癌症信号通路的 PROGENy 和转录因子的 DoRothEA。一般采用超几何分布检验、GSEA 或 GSVA 进行富集分析。研究发现富集分析对基因集的选择敏感性大于统计方法,因此应当谨慎选择数据库。decoupleR 等框架提供了多个不同数据库的访问方法。为常规转录组开发的方法可以用于单细胞数据,但一些基于单细胞的方法(比如 Pagoda2),效果可能优于前者。\n检测细胞组成的变化 Deciphering changes in cell composition 成分分析比较的是不同细胞类型的相对丰度。单变量统计模型,比如泊松回归或是 Wilcoxon 秩和检验可能将部分细胞类型误报为有显著差异,而实际只是样本组成引起的假象。有专门为单细胞设计的 scDC、scCODA 和 tascCODA 测试方法。\n推断扰动效应 Inferring perturbation effects 利用细胞培养体系,同时进行大规模多重条件处理细胞的方法称为扰动(perturbations),perturb-seq 或 CROP-seq 等最新技术允许使用多模态数据、全基因组扰动和组合扰动对混池 CRISPR–Cas9 筛选进行分析。\n细胞通讯分析 Communication events across cells 细胞通讯分析利用配体、受体及其相互作用的数据库来预测细胞间相互作用。推荐使用 LIANA,它提供了多种方法和数据库。此外还有CellChat、CellPhoneDB、SingleCellSignalR;提供细胞内活动的补充估计的 Nichenet 和 Cytotalk。\n原文 原文中还有关于单细胞 ATAC、单细胞蛋白组、空间转录组等内容,但目前还不太关注,就先不记录了。如果有需要还请阅读原文。\nBest practices for single-cell analysis across modalities\n","permalink":"https://yorks0n.github.io/posts/read-single-cell-best-practice/","summary":"Best practices for single-cell analysis across modalities","title":"【读文献】单细胞分析最佳实践"},{"content":"文件准备 将Shiny用到的server.R和ui.R一起放在app文件夹中\n./app: server.R ui.R 写个Dockerfile,把用到的包都写在 install.r 后面\nFROM rocker/r-base:latest LABEL maintainer=\u0026#34;email \u0026lt;[email protected]\u0026gt;\u0026#34; RUN apt-get update \u0026amp;\u0026amp; apt-get install -y --no-install-recommends \\ sudo \\ libcurl4-gnutls-dev \\ libcairo2-dev \\ libxt-dev \\ libssl-dev \\ libssh2-1-dev \\ \u0026amp;\u0026amp; rm -rf /var/lib/apt/lists/* RUN install.r shiny shinyBS dplyr stringr RUN echo \u0026#34;local(options(shiny.port = 3838, shiny.host = \u0026#39;0.0.0.0\u0026#39;))\u0026#34; \u0026gt; /usr/lib/R/etc/Rprofile.site RUN addgroup --system app \\ \u0026amp;\u0026amp; adduser --system --ingroup app app WORKDIR /home/app COPY app . RUN chown app:app -R /home/app USER app EXPOSE 3838 CMD [\u0026#34;R\u0026#34;, \u0026#34;-e\u0026#34;, \u0026#34;shiny::runApp(\u0026#39;/home/app\u0026#39;)\u0026#34;] 按以下方式进行构建\n# name of the image export IMAGE=\u0026#34;yorks0n/trxiv_shiny\u0026#34; # build image docker build -t $IMAGE . # run and test locally docker run -p 8080:3838 $IMAGE 居然就行了!\n部署在 Railway 上 # 安装 brew install railway # 登录 railway login 创建一个项目,并输入项目名称\n➜ railway init \u0026gt; Project Name TRxiv_shiny Created project TRxiv_shiny on Personal 虽然当前目录下有个 Dockerfile 了,但是这 XX 的 railway 部署时候端口和默认 docker 的不太一样,或者我没找到哪里设置,所以如果要部署在 railway 上,还需要改一下 Dockerfile。虽然在这指定了ENV PORT=3838,但实际上 railway 每次开的端口都不太一样,所以标准 docker 的写法不太行。\nFROM rocker/r-base:latest LABEL maintainer=\u0026#34;Yorkson \u0026lt;[email protected]\u0026gt;\u0026#34; RUN apt-get update \u0026amp;\u0026amp; apt-get install -y --no-install-recommends \\ sudo \\ libcurl4-gnutls-dev \\ libcairo2-dev \\ libxt-dev \\ libssl-dev \\ libssh2-1-dev \\ \u0026amp;\u0026amp; rm -rf /var/lib/apt/lists/* RUN install.r shiny shinyBS dplyr stringr RUN addgroup --system app \\ \u0026amp;\u0026amp; adduser --system --ingroup app app WORKDIR /home/app COPY app . RUN chown app:app -R /home/app USER app EXPOSE 3838 ENV PORT=3838 # 研究后发现,这里以获取PORT的方式,才能在 Railway 中部署 CMD [\u0026#34;R\u0026#34;, \u0026#34;-e\u0026#34;, \u0026#34;shiny::runApp(\u0026#39;/home/app\u0026#39;, host = \u0026#39;0.0.0.0\u0026#39;, port=as.numeric(Sys.getenv(\u0026#39;PORT\u0026#39;)))\u0026#34;] railway up 参考资料 在Windows系统下,基于WLS从零开始部署我的 R shiny项目到 Docker 中,并将镜像发布到 Docker Hub(内附详细操作流程)_douerw的博客-CSDN博客\nDockerizing Shiny Applications\nDockerized Shiny Apps with Dependencies\n","permalink":"https://yorks0n.github.io/posts/docker-pack-shiny-app/","summary":"介绍了如何将 Shiny App 打包成 Docker 格式,方便在不同设备环境下托管","title":"Docker 打包 Shiny App"},{"content":"将JS写的抓取 Altmetric 热门预印本,与 bioRxiv API 结合后储存在 csv 文件中的过程,部署在 Github Action 中。官方文档写的顺序都有点混乱,网上找到的教程又经常都比较老了,因此自己记录一个。\n新建Github仓库 新建一个public仓库,名叫TRxiv,并将远程仓库git clone到本地。\ngit clone [email protected]:Yorks0n/TRxiv.git cd TRxiv 创建一个动作元数据文件 要让仓库里能被以Action的形式直接调用,需要在根目录中创建一个action.yml配置文件,可以在这个文件中指定Action的输入和输出,调用的参数及运行环境\n# action.yml name: \u0026#39;trxiv\u0026#39; description: \u0026#39;Tracking popular bioRxiv and medRxiv preprints\u0026#39; runs: using: \u0026#39;node16\u0026#39; main: \u0026#39;dist/index.js\u0026#39; 准备运行的代码 手动将写好的JS脚本拷贝进来,完整代码在此 Yorkson/TRxiv。\n# 在这里初始化一下npm npm init -y 准备一个.gitignore文件,防止在推送的时候把不必要的文件放到储存库,可以用下面这个工具,或者自己写一下,比如这里就可能有node_modules\nhttps://www.toptal.com/developers/gitignore\n文件推送到远程仓库 然后push到远程仓库\ngit add . git commit -m \u0026#34;Initialize\u0026#34; git push 打包软件 因为前面把node_modules 从上传的文件列表中忽略了,但脚本index.js内有些依赖的包,所以最好把软件和依赖打包在一起,官方推荐用ncc\nnpm install @vercel/ncc 然后对index.js 进行打包\nncc build index.js -o dist 打包产物会存放于dist/index.js\n创建工作流 在本地创建.github/workflows/main.yml,这个文件实际确定了 Github Action 的行为,此yml格式文件一定要注意正确的缩进。\n配置文件内容:\n# main.yml ## 动作的名称 name: \u0026#39;TRxiv update\u0026#39; # 触发条件 ## 条件1,代码push进仓库 ## 条件2,定时任务,在UTC 10和22点,即北京时间18点和6点运行 on: push: schedule: - cron: \u0026#39;0 10,22 * * *\u0026#39; # jobs 定义了要执行的一系列任务 jobs: ## 这个job的名称 TRxiv_update_job: ## runs-on 内置运行任务的server类型 runs-on: ubuntu-latest name: Update the csv file steps: ## 必须有这一步,让运行的文件夹成为一个git repo - uses: actions/checkout@v3 ## 运行脚本,指向我们的repo - name: \u0026#39;run script\u0026#39; uses: Yorks0n/TRxiv@main ## 运行完后,把运行产生在本地的data.csv更新回仓库中 - name: Commit files run: | git config --local user.email \u0026#34;github email adress\u0026#34; git config --local user.name \u0026#34;github user name\u0026#34; git pull git add README.md git add data.csv git commit -m \u0026#34;update data.csv\u0026#34; shell: bash ## 使用秘钥确认具有上传权限,同时以秘钥方式提交不会触发push action,避免陷入loop - name: Push changes uses: ad-m/github-push-action@master with: github_token: ${{ secrets.MY_GIT_TOKEN }} branch: main 再次将文件推送到远程仓库 git add . git commit -m \u0026#34;Update Workflow\u0026#34; git push 后续更新 每次想更新修改前,先在目录中把最新版的环境拉下来\ngit pull 修改过脚本后,要重新打包用到的代码:ncc build index.js --license licenses.txt\n然后再提交回仓库\n参考 How to Build Your First JavaScript GitHub Action\n如何使用 Github Actions 自动抓取每日必应壁纸?\nPermission denied to github-actions[bot]\nCreating a JavaScript action - GitHub Docs\n","permalink":"https://yorks0n.github.io/posts/deploy-trxiv-github-action/","summary":"\u003cp\u003e将JS写的抓取 Altmetric 热门预印本,与 bioRxiv API 结合后储存在 csv 文件中的过程,部署在 Github Action 中。官方文档写的顺序都有点混乱,网上找到的教程又经常都比较老了,因此自己记录一个。\u003c/p\u003e\n\u003ch2 id=\"新建github仓库\"\u003e新建Github仓库\u003c/h2\u003e\n\u003cp\u003e新建一个public仓库,名叫TRxiv,并将远程仓库\u003ccode\u003egit clone\u003c/code\u003e到本地。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003egit clone [email protected]:Yorks0n/TRxiv.git\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecd TRxiv\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"创建一个动作元数据文件\"\u003e创建一个动作元数据文件\u003c/h2\u003e\n\u003cp\u003e要让仓库里能被以Action的形式直接调用,需要在\u003cstrong\u003e根目录\u003c/strong\u003e中创建一个\u003ccode\u003eaction.yml\u003c/code\u003e配置文件,可以在这个文件中指定Action的输入和输出,调用的参数及运行环境\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# action.yml\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ename: \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;trxiv\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edescription: \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;Tracking popular bioRxiv and medRxiv preprints\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eruns:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e using: \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;node16\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e main: \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;dist/index.js\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"准备运行的代码\"\u003e准备运行的代码\u003c/h2\u003e\n\u003cp\u003e手动将写好的JS脚本拷贝进来,完整代码在此 \u003ca href=\"https://github.com/Yorks0n/TRxiv\"\u003eYorkson/TRxiv\u003c/a\u003e。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 在这里初始化一下npm\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003enpm init -y\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e准备一个\u003ccode\u003e.gitignore\u003c/code\u003e文件,防止在推送的时候把不必要的文件放到储存库,可以用下面这个工具,或者自己写一下,比如这里就可能有\u003ccode\u003enode_modules\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://www.toptal.com/developers/gitignore\"\u003ehttps://www.toptal.com/developers/gitignore\u003c/a\u003e\u003c/p\u003e\n\u003ch2 id=\"文件推送到远程仓库\"\u003e文件推送到远程仓库\u003c/h2\u003e\n\u003cp\u003e然后push到远程仓库\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003egit add .\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003egit commit -m \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;Initialize\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003egit push\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"打包软件\"\u003e打包软件\u003c/h2\u003e\n\u003cp\u003e因为前面把\u003ccode\u003enode_modules\u003c/code\u003e 从上传的文件列表中忽略了,但脚本\u003ccode\u003eindex.js\u003c/code\u003e内有些依赖的包,所以最好把软件和依赖打包在一起,官方推荐用\u003ccode\u003encc\u003c/code\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003enpm install @vercel/ncc\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e然后对\u003ccode\u003eindex.js\u003c/code\u003e 进行打包\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003encc build index.js -o dist\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e打包产物会存放于\u003ccode\u003edist/index.js\u003c/code\u003e\u003c/p\u003e","title":"部署预印本追踪 TRxiv 到 Github Action"},{"content":"兜兜转转又开始写 Blog 了,之前几次都没写过多少文章。实际花在折腾 Blog 的时间,远比真正写东西的时间更多。因为没啥值得看的内容,页面无法访问了也一直没有去解决。\n但这次再开博客,倒不是有了汩汩冒出的表达欲,而是自一年前在少数派开始写点文章后,逐渐感受到了输出的重要。之前学习各种东西的过程中一直在输入,会记下不少笔记,但很少整理,几乎就堆在各种笔记软件中。时隔很久再去看,也还是最初的样子,往往看的时候已经不太记得当初某一步为什么要这样设置,或是做了哪些没有记录下来的操作。因此,准备把自己折腾过的东西整理成可以复现的形式,也是更好掌握和回顾知识的过程。\n另一方面,在这几年的学习过程中,几乎都是通过搜索引擎与自学研究各种东西,看到高质量的内容中,除了诸多官方提供的教程,就是许多人在博客中记录的学习心得,受益良多。因此,假如能进行一定输出,说不定也能在未来的哪一天帮上其他人的忙。\n最后,从去年年底开始,以 ChatGPT 为首的大语言模型,不由分说地闯进了人们的生活中。目前,我也几乎每天都会用到它,但几乎只局限在遇到不懂问题时候的 Q\u0026amp;A。但 LLM 的一大限制因素就在于优质内容的输入,在内容工厂的摧残下,中文互联网的内容良莠不齐。因此也希望我写的文章,能在将来的某一天,为模型输出更好的结果贡献一点微小的概率。\n又及,还没有想好怎么对文章进行分类,索性先写起来。同时会把以前写过的东西也都整理到一起,因此日期早于这篇文章的内容,都应该是在其他地方已经发过的。整理搬运过程估计还会持续很久,但已经发现 Gridea 插入图片不太趁手了,估计迟早会再换种部署方式,也许是 Hugo 吧。\n","permalink":"https://yorks0n.github.io/posts/hello-again/","summary":"我为什么又开始写 Blog 了?","title":"Hello, again"},{"content":"分享最近看到的一组有意思的数据可视化。 由 ferdio 出品的,主题为「1 dataset 100 visualizations」。他们选用了一组非常简单的数据,用一百种不同的图进行可视化,借此「展示数据可视化的多样性和复杂性,以及如何使用有限的视觉元素来讲述不同的故事」。尽管使用了相同的原始数据,但每张图都有其独特的重点,传递出的信息也不尽相同。 我计划从中选几个有代表性的图,并尝试解读这种可视化突出了数据怎样的特点。 先从比较常见的开始,下面两张图都是将数值编码成了长度,算是最常见的柱状图了。依照组合顺序的不同,左图将相同年份的数据摆在一起,更能突出相同年度中,几个国家之间谁的数量更多;右边的图将同一国家两个年度的数据放在一起展示,更能体现出每个国家世界遗产数量都在上升这个趋势。 与此同时,假如使用堆积柱状图,则突出的是两个年度,这三个国家世界遗产总量的增长趋势。 另外,上面几张图中还有一个特点,它们都将各个部分的具体数值直接标注在了对应的区域。这种方式蛮好,可以减轻看图时「视线需要在坐标轴和数据间反复切换,估算数值」所产生的负担。在这样处理的图中,即使完全删去纵坐标轴也不影响数据解读。\n下面这两张图则是让我比较眼前一亮的(尤其是下面第二张),仔细去看,它们虽然形状不太相似,但实际是几乎一样的两张图——用在一条直线上的位置标记多个数据点的数值。我觉得它们好在以下几个方面:\n清晰明了,无论是比较同一年度各个国家的数值(点的位置),还是增长幅度(两点间的连线长度)都一目了然 节约空间,如果把第二张图放平,只占据柱状图单个柱子的空间,就足以展示六条柱子所传达的信息 可以体现出跨越性的增长与压倒性的优势:丹麦(橙色)的世界遗产数量从04年的不如挪威(深蓝色),到22年超越挪威,这种跨越性的增长趋势在这两张图中一目了然,反观上面的几个柱状图,都需要在柱子长度间反复多次比较数值,才能观察到这种变化;另一方面,瑞典(蓝色)无论哪个年度的数量都远超另外两个人国家,这个结论在前面的图中也能通过比较得出,但在这张图中尤其清晰。 究其原因,这两张图将本身分散的长度、位置信息合并在了同一条线上,使得相互间的比较更为容易。但它也有一些缺点: 假如是多个时间点,比如三个年度,在这张图中就容易造成混乱 这批数据的变化趋势一致,都是22年的数值高于04年,假如在不同国家间,有的数量增加,有的数量减少,可能就需要带箭头的线段才能表示年份间的变化趋势。 同样,假如不放在一条直线上,而是按位置分开的图也有,比如下面这张图。上面提到的一些优点,比如增长幅度的大小、丹麦超越性的增长、瑞典压倒性的数量也都可以看到,但少了在原位的国家名称与数量标注,感觉就没那么醒目了。但这张图也有它的优点:使用颜色来表示年份而不是国家,假如有国家的数量下降了,在这张图上就会很好地展现出来。 这次就先写这些,溜了溜了。 如果对更多可视化感兴趣,或是想找找新的画图思路,可以直接去原网站查看可视化结果。 参考资料 1 dataset. 100 visualizations.\n","permalink":"https://yorks0n.github.io/posts/interesting-1-dataset-100-visualizations/","summary":"分享最近看到的一组有意思的数据可视化","title":"1 dataset 100 visualizations 中有意思的可视化"},{"content":"注:本文首发于少数派,此处有删改,您可以 前往此处 阅读修订后版本。\n色彩模型 人眼的色彩感知 我们能看到颜色主要与人眼的生理特性有关,视杆细胞和视锥细胞在其中发挥了重要作用。其中,视杆细胞主要负责感受光的明暗,视锥细胞负责感受不同波长的光。大多数人有三种不同类型的视锥细胞,它们各自对不同波长的光有不同的灵敏度:红色、绿色和蓝色。当某些视锥细胞缺失或敏感度发生变化,将导致色觉异常。\n三种视锥细胞对不同光波长的光具有不同的敏感度。来源:\nRGB 模型 RGB 模型绝对称得上是数字时代最为常见的色彩模型,它将红色(R)、绿色(G)、蓝色(B)三种颜色的光,按照不同比例混合,得到各种不同的颜色。RGB 模型如此流行,一方面是因为它符合人眼对色彩的感知过程(对应三种视锥细胞),另一方面,屏幕上的每个像素也都是由红绿蓝三个次级像素组成,直接以此方式编码, 极大地方便了在屏幕上进行显示。\nRGB色彩模型\nHSB/HSV 虽然 RGB 模型既常用又方便理解,但它并不符合人对颜色的直观感受。我们看到某个颜色时,不会把它拆分成红绿蓝三个组分,而是直接感知三种视锥细胞叠加后的效果。因此,后来又出现了称为 HSV 的色彩模型(也称HSB)。\n你也许在选颜色时见到见过这种模型,它仿佛将所有颜色放入了一个倒置的圆锥。\nHSV 模型采用三个维度的数值描述颜色:\n色相(Hue),圆锥的最外围一圈,即它是什么颜色; 饱和度(Saturation),圆锥上某个点到中轴的距离,离中轴越近饱和度越低,颜色也越接近黑白灰; 亮度(Brightness 或 Value),圆锥上点到尖端的距离,越接近尖端,亮度越低(越黑)。 那 HSV 相比 RGB 直观在哪里?举个例子,左边颜色只降低亮度后,可以得到右边的颜色;但要是通过 RGB 来调整,就需要同时调整红绿蓝三种颜色值,颜色很容易一下就偏得没边了。\n为什么要有不同的色彩模型 一个很好的例子是地图制图投影方式和飞行路径图,我们可以将不同的色彩空间模型视为不同的地图投影方式。根据选择地图类型(色彩空间)的不同,同样的飞行路径可能看起来大不一样。\n墨卡托投影地图上从洛杉矶到莫斯科、纽约到莫斯科的飞行路线。\n正射投影\n根据数据类型选择颜色 类别色阶(Categorical color scales) 类别数据使用类别色阶。\n当数据是一组类别时,它们没有内在的顺序,比如不同的分组实验材料。下图中不同的国家,并不会说某个国家比另一个国家排在前面或是后面,就属于类别数据,因此要用类别色阶(Categorical color scales)。\n何为类别色阶?红色、黄色、蓝色,它们适合区分没有内在顺序的类别,其中一种颜色并不比另一种颜色更重要。\n单向色阶(Sequential color scales) 连续色阶是从暗到亮/从亮到暗的颜色渐变,它们适合可视化从低到高变化的数值数据,比如温度、质量或浓度。\nFrom Chroma.js Color Palette Helper\n这时并不是说就不能分组,你依然可以将特定数值划分成一个个区间,对每个区间采用一个颜色。\n或是不划分区间\n注意⚠️:\n在单向的顺序色阶中,只能使用一到两种色调,比如浅蓝色到深蓝色(单色,蓝色),或是从浅黄色到深蓝色(双色,蓝色和黄色)。\n好的顺序色阶中,变化的并不只是颜色的色相(Hue),颜色的亮度(Lightness)与饱和度也在同步变化。\n对低值使用浅色,对高值使用深色(亮度更低、饱和度更高)。使用颜色渐变时,请确保亮色代表低值,而深色代表高值。对于大多数读者来说,这将是最直观的\n双向色阶(Diverging color scales) 双向色阶(Diverging / bipolar / double-ended color scales)与单向色阶类似,但是它不再是亮度或饱和度的从低到高变化,它中间亮度更高,然后向两侧色调与亮度同时变化。\n双向色阶通常用于:\n正值和负值这样两端有明确对立关系的值 有个有意义的中间点,比如0、50%、平均值、选定的阈值 同单向色阶一样,双向色阶也可以再分为分组和不分组两种:\n双向,分组\n双向,不分组\n从色彩集中选择颜色 这里介绍四个工具\nThe Data Viz Color Picker\nColorpicker for data\nCARTOColors - CARTO\nchroma.js palette helper\nData Viz Color Picker PALETTE\nSINGLE HUE\nDIVERGENT COLOR\nColorpicker for data CARTOColors Sequential schemes\nDiverging schemes\nQualitative schemes\n注意事项 色觉异常 前面提到,由于有三种视锥细胞存在,我们可以感知红绿蓝三种颜色极其组合。如果其中某种视锥细胞的灵敏度不够,那么会导致色弱;如果某种细胞完全不起作用,那么就会导致色盲。因此有三种不同类型的色弱,和三种不同类型的色盲。\n在人群中,色弱相比色盲更加常见,大约6-7%的男性有某种色弱,而大约2-3%的男性是色盲。\n因此,某些颜色的组合应当避免,比如红色-绿色-棕色。\n我们比较熟悉的荧光图中也会倡议使用洋红色+绿色的组合,而不是红色和绿色的组合。\n另一方面,在选择颜色时,不仅在色相(Hue)上发生变化,也让饱和度和亮度同时变化,也有助于增加色彩的区分度。一些工具会给出相同配色在不同色觉异常人士眼中的效果。\n还有一种方式,是用颜色和模式同时来表示不同的类别,比如加上阴影,或是采用不同的虚实线段。\nLess is more 如非必要,勿增实体\n是否有替代渐变色的数值表示方式(能不用,就不用)\n比如采用长度(条形图)、位置(点图)或是面积的大小\n避免同时使用过多颜色(能少用,不多用)\n如果图中使用了超过七种颜色,可能要考虑其他的图表类型,或是将类别组合在一起。\n颜色本身是帮助读者区分类别的,但是颜色越多,就越难快速阅读和理解,在读图时将不得不反复在图例和图形间来回查阅。\n更好地分配颜色 对相同变量使用相同颜色,简化理解过程\n配合图例解释颜色指代的内容:图形的大小代表什么、深浅是对应哪个变量,这些都需要解释清晰。\n详略得当地使用颜色,将不重要的元素用灰色或其他非常浅的颜色来表示,可以突出需要重点关注的数据\n保证对比度,避免使用互补色(比如红配绿、橙配蓝)\n避免使用彩虹色渐变\n彩虹色渐变有几个大的问题:\n它的颜色变化并不均匀,其中绿色占据了几乎1/3的范围 各种颜色之间的亮度变化不均一 参考资料 Star:\nColorimetry and the Cartography of Color\n色彩空间\n弄清色彩的作用和表达 - 少数派\n不同的色彩模型\nWhich color scale to use when visualizing data - Datawrapper Blog\n根据数据类型(离散、连续)选择颜色\nWhat to consider when choosing colors for data visualization\n一些颜色安排上的注意事项\nSpectrum, Adobe\u0026rsquo;s design system\n选择颜色的注意事项\nHow The Rainbow Color Map Misleads\n彩虹色渐变为什么不合适\nHow your colorblind and colorweak readers see your colors - Datawrapper Blog\n色觉异常\nOther:\nWhen to use sequential and when to use diverging color scales - Datawrapper Blog\nWhen to use classed and when to use unclassed color scales - Datawrapper Blog\nYour Friendly Guide to Colors in Data Visualisation\n10 ways to use fewer colors in your data visualizations - Datawrapper Blog\n如何减少使用的颜色数量\nA map from Great Circle Mapper\n大圆航线\nColoring for Colorblindness\n色觉异常的颜色选择\n","permalink":"https://yorks0n.github.io/posts/color_guide/","summary":"论文作图时用得上的配色技巧与工具","title":"论文可视化配色简易指南"},{"content":"注:本文首发于少数派,您可以 前往此处 阅读修订后版本。\nKarabiner 全称 Karabiner-Elements[^下文简称为 Karabiner],是 macOS 上的一款功能强劲的改键工具,可以将键盘上的按键映射成其他一个或多个按键组合。然而,Karabiner 使用JSON 作为配置文件,非常繁琐且不易理解,给上手带来了很高的门槛。\n上图展示了 Karabiner 中与 Goku 中,实现相同效果所需要的写法差异。\n于是,有人专门为其制作了一个工具「Goku」,借助 Goku 可以方便地为 Karabiner 进行配置。\n准备工作:\nKarabiner-Elements 可以从官网进行下载 Goku 使用 Homebrew 进行安装:brew install yqrashawn/goku/goku 在 Karabiner 中确保配置文件 Profiles 选择默认的 Default 前往 ~/.config/目录,创建名为 karabiner.edn 的 Goku 配置文件 参考下文进行配置文件的编辑,每次编辑完后在终端中执行 goku 使修改生效 将 Caps Lock 变为键盘功能的中枢 通常,我们将⌃Control + ⌥Option + ⇧Shift + ⌘Command 同时按下的组合称为 Hyper 键,因为程序内置的快捷键不会预设这么复杂的组合,因此使用 Hyper 键设定快捷键,能最大程度上避免与预设发生冲突。\n大写锁定键 Caps Lock 位于键盘左侧中间,用起来很顺手,但我只用它切换输入法,输入大写字母靠 ⇧shift,因此这里先对它下手,你也可以选择其他顺手且不常用的按键。\n以下的 Goku 配置文件 karabiner.edn 写法,可以将大写锁定键修改为 Hyper 键,这时只需要按下这一个键,就可以发挥 ⌃Control + ⌥Option + ⇧Shift + ⌘Command 同时按下的效果。\n{ :main [ {:des \u0026#34;caps_lock -\u0026gt; hyper\u0026#34; :rules [ [:##caps_lock :!CTOleft_shift] ]} ] } 然而,如果只是将 Caps Lock 转化为 Hyper 键,它会失去本身切换输入法的效果。幸好 Karabiner 支持在按键单独按下与组合按下时,为触发不同的效果。\n以下写法可以让 Caps Lock 与其他键一同按下时变为 hyper 键,单独按下时触发 Control+Space 切换输入法。\n{ :main [ {:des \u0026#34;caps_lock -\u0026gt; Ctrl+space(alone) and caps_lock -\u0026gt; hyper\u0026#34; :rules [ [:##caps_lock :!CTOleft_shift nil {:alone :!Tspacebar}] ]} ] } 以下是一些常用按键在 Goku 中的简化写法:\n;; ! | means mandatory - modifier(s) alone when pressend change behavior ;; # | means optional - modifiers are optional (but at least one necessary) ;; :!Ca is keycode :a and prefix a with !C ;; C | left_command ;; T | left_control ;; O | left_option ;; S | left_shift ;; F | fn ;; Q | right_command ;; W | right_control ;; E | right_option ;; R | right_shift ;; ## | optional any ;; !! | command + control + optional + shift (hyper) 而要知道键盘上每个按键各叫什么名字,可以使用 Karabiner 配套的 Karabiner-EventViewer 进行查看。\n结合 Keyboard Maestro 实现快速搜索 单靠 Karabiner 只能发挥其一半的功力,要想发挥其全部实力,还是要与 Keyboard Maestro(下称 KM)或是 Alfred 这些支持自动化的工具搭配,才能达到强强联合的效果。这里以 KM 为例,实现快速搜索选中的内容。\n在 KM 中创建如下图的 Macro,为其指定 Hyper + S 的组合键,这样只需要选中想搜索的内容,按下快捷键即可使用 Google 进行搜索。\n同时,借助 KM 独特的冲突调色盘功能,当你为多个 Macro 设定了相同快捷键,按下快捷键后会触发选择界面,借此只需记忆一个快捷键,便可触发多种不同的搜索功能。\nHyper + 字母实现程序快速切换 日常使用时,常常需要在不同的应用间来回切换。cmd + tab 虽然可行,但每次的应用顺序不固定,还要找到想切换到的程序,甚至因此诞生了一些专门为切换应用而生的工具。利用 Karabiner 搭配 Keyboard Maestro,即可实现 Hyper + 字母 一键切换应用。\n在 Keyboard Maestro 中添加 Macro, 选择 Activate a Specific Application 即可,配置成如下图即可在激活此 Macro 时切换到 Chrome。\n这时,如果在 KM 中将 New Trigger 设置为按键的 Hyper + c,即可在按下此组合键时快速切换到 Chrome。\n但这毕竟是一篇介绍 Karabiner 的文章,因此我演示一下如何在 Karabiner 的配置文件中,直接激活特定的 Macro。\n以下配置文件可以实现 Hyper + C 切换到 Chrome 的效果。\n{ :templates {:km \u0026#34;osascript -e \u0026#39;tell application \\\u0026#34;Keyboard Maestro Engine\\\u0026#34; to do script \\\u0026#34;%s\\\u0026#34;\u0026#39;\u0026#34; } :main [ {:des \u0026#34;caps_lock -\u0026gt; Ctrl+space(alone) and caps_lock -\u0026gt; hyper\u0026#34; :rules [ [:##caps_lock :!CTOleft_shift nil {:alone :!Tspacebar}] [:!!c [:km \u0026#34;open: chrome\u0026#34;] ] ;;caps+c open Chrome ]} ] } 我在前面模板的基础上增加了两部分:\n开头利用 :templates 创建了一个名为 :km 的脚本,可以快速激活 KM 中的Macro; 在 :rules 中新增加了一行规则,:!!c 表示 Hyper + C 的组合键[^这里 !! 是 hyper 键的缩写写法],:km \u0026quot;open: chrome\u0026quot; 则表示调用前面创建的 km 脚本,并执行 \u0026quot;open: chrome\u0026quot; 这个 Macro。 进阶,让每个键都能成为修饰键 Hyper 键只有一颗,用久了总有因为键位冲突感到不够的那天,比如我既想用 S 键触发 Search,又想用它激活 Sorted 3。这部分我将介绍如何利用层(layer)的概念,让键盘上的每个键都能成为独一无二的修饰键。\n所谓层,可以理解为按下某个键后,键盘上其他键的功能随之发生变化,例如下图就是按下 option 键后键盘的变化,我们可以称之为 option 层。\n如下规则定义了一个称为「semicolon-mode」的层,在这里我将使用频率较低的分号;定义为触发按键:\n:semicolon [\u0026quot;semicolon-mode\u0026quot; 1] 指按下分号「semicolon」后,将变量 semicolon-mode 设置为 1,即进入「semicolon-mode」层; :afterup [\u0026quot;semicolon-mode\u0026quot; 0] 指松开分号后,将变量 semicolon-mode 设置为 0,即退出「semicolon-mode」层; 单独按下依然为分号本身 :alone :semicolon 。 在 [:hyphen [:km \u0026quot;insert: underline\u0026quot;] [\u0026quot;semicolon-mode\u0026quot; 1]] 这里,我定义了按下减号- ,触发 KM 中名为 \u0026quot;insert: underline\u0026quot; 的 Macro,输出一个下划线,这个规则只在[\u0026quot;semicolon-mode\u0026quot; 1] 时(即按住分号时)才有效。\n{ :templates {:km \u0026#34;osascript -e \u0026#39;tell application \\\u0026#34;Keyboard Maestro Engine\\\u0026#34; to do script \\\u0026#34;%s\\\u0026#34;\u0026#39;\u0026#34; } :main [ {:des \u0026#34;This is the semicolon-mode\u0026#34; :rules [[:semicolon [\u0026#34;semicolon-mode\u0026#34; 1] nil {:afterup [\u0026#34;semicolon-mode\u0026#34; 0] :alone :semicolon}] [:hyphen [:km \u0026#34;insert: underline\u0026#34;] [\u0026#34;semicolon-mode\u0026#34; 1]] ;; semicolon - to insert _(underline) ]} ] } 结语 「花一些时间,折腾一点小东西,收获一个没多大用的成果,感到巨大的快乐」,这是我对摸鱼的定义。摸鱼摸得久了,总能折腾出些有意思的东西。目前,我每天都用这些快捷键输入一些常用短语,切换程序或是快速搜索,省下的时间可能并没有多少,但是有种莫名的快乐,我觉得这就足够了。\n相关文章 macOS 改键利器:Karabiner-Elements 使用详解 - 少数派\n使用 Karabiner 改善 Poker 键盘体验 - 少数派\n让键盘变成你想要的样子:改键利器 Karabiner-Elements - 少数派\n参考资料 Karabiner God Mode\n使用 Goku 配置 Karabiner\nyqrashawn/GokuRakuJoudo\n","permalink":"https://yorks0n.github.io/posts/karabiner/","summary":"如何借助 Goku 书写 Karabiner 配置文件","title":"Karabiner 助力,让你的键盘操作快人一步"},{"content":"What 这是我日常会用到,所以整理出来的主要与植物学、基因组学有关的在线数据库集合。\n链接在此:database\nHow-to 我利用了「#标签」的形式对链接进行分类,因此在检索的时候,可以直接点击下面的标签进行选择,也可以在搜索框中以「#标签名」的形式输入一个或多个标签进行筛选,多个标签之间使用空格隔开。\n举个例子,假如想寻找和拟南芥蛋白有关的数据库,则可以在下面的标签中依次点击「#拟南芥」和「#蛋白」,也可以直接在搜索框中输入这两个标签。\n补充说明:\n如果这个数据库只包含一个物种的数据,我会给它打上「#物种名」的标签,但如果它同时带有多物种内容,比如 NCBI 或是 Ensembl plants,我就不会给它打物种名的标签。 有些数据库我也没有想好怎样用最简短的标签进行概括,所以标签描述不一定完备,也欢迎提修改意见。 Why and why 为什么要做这个 知识共享也好,流动着的知识才是好知识也好,可能就是我觉得有意思吧。\n为什么不用文件夹 文件夹组成的是一种树状结构,然而每个数据库的属性并不是整齐的树状。比如一个数据库,即可以带有「拟南芥」的属性,表明它主要是一个拟南芥的数据库,同时它还可能带有一个「蛋白」的属性,表明其是蛋白质结构、或是蛋白修饰的数据库,因此这样的数据库并不能单一地根据物种或是数据类型进行分类。\n为什么使用 Raindrop.io 我使用了书签管理服务 Raindrop,直接对其中一个文件夹进行共享,因为一方面发现它很方便,不论是检索还是发布;另一方面,我也想过用 Notion 或是飞书的在线文档形式,可能会更稳定一点,但是我懒,不想再一条条输一遍了,也许之后发布方式会改吧。\n后续计划 如何更新 欢迎提意见和建议,包括如何改进标签,更准确地描述数据库;有哪些新的数据库值得加入进来,Et cetera。可以留言或直接与我联系。\n","permalink":"https://yorks0n.github.io/posts/my-bioinfomatics-db-collection-ver20220528/","summary":"这是我日常会用到,整理出来的主要与植物学、基因组学有关的在线数据库集合。","title":"我的植物组学数据库合集 Ver.20220528"},{"content":"注:本文首发于少数派,您可以 前往此处 阅读修订后版本。\n前言 本文介绍了基于 n8n 搭建的自动化平台,实现监控 RSS 更新并推送到飞书消息的功能。\n文末会列举一些实现此工作流的其他方式,包括发送请求和接收提醒的手段。同时,n8n 还可以通过模块组合,实现更多更复杂的功能,本文只作为抛砖引玉。\n阅读本文可能需要一定 Linux 基础知识。\nn8n 是什么 n8n 是一个开源的自动化流程搭建工具,可以实现类似 IFTTT 的效果,比如「如果明天下雨,就推送要带伞的消息」。优点是开源、可以自己部署并将信息都储存在本地,同时可以与 Github、Telegram、Slack 等各种服务实现联动,以搭建自动化工作流。\n利用 Docker 安裝 n8n n8n 可以直接下载 Win 或是 Mac 版本,快速在本地使用,但如果想更稳定地长期运行,更适合部署在云服务器、树莓派或 NAS 等工具上。\n这里以在云服务器上使用 Docker 进行部署为例,更多安装方式可参考 Installation guides for n8n。\n假设已经安装好了 Docker,那么 n8n 的部署就非常简单,先新建一个文件夹储存数据。\n# 创建数据储存文件夹 mkdir ~/n8n-data 复制运行下面的代码,利用 Docker 安装 n8n。如果云服务器有防火墙,需要把对应的端口打开,这里需要打开5678的 TCP 端口。\n# 利用Docker安装运行n8n docker run -d \\ --name n8n --restart unless-stopped \\ -p 5678:5678 \\ -v ~/n8n-data:/home/node/.n8n \\ -e GENERIC_TIMEZONE=\u0026#34;Asia/Shanghai\u0026#34; \\ n8nio/n8n 稍作等待,等 Docker 安装完成后,如果一切顺利,访问服务器ip地址:5678就能看到 n8n 的运行页面了,初次进入需要创建账号密码。\n点击右上角的 New blank workflow 即可开始创建,也可以从软件提供的 Workflow 示例中,选择自己想部署的自动化流程。\n这里以搭建一个 RSS 更新自动推送到飞书的机器人为例。\n搭建飞书 RSS 推送机器人 以下是我配置好的一个流程模板,复制以下内容粘贴到 n8n 新建 workflow 的页面。\n{ \u0026#34;nodes\u0026#34;: [ { \u0026#34;parameters\u0026#34;: { \u0026#34;url\u0026#34;: \u0026#34;https://sspai.com/feed\u0026#34; }, \u0026#34;name\u0026#34;: \u0026#34;RSS Feed Read\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;n8n-nodes-base.rssFeedRead\u0026#34;, \u0026#34;typeVersion\u0026#34;: 1, \u0026#34;position\u0026#34;: [ 160.5, 440 ] }, { \u0026#34;parameters\u0026#34;: { \u0026#34;conditions\u0026#34;: { \u0026#34;number\u0026#34;: [ { \u0026#34;value1\u0026#34;: \u0026#34;={{new Date($node[\\\u0026#34;Latest Read\\\u0026#34;].data[\\\u0026#34;latestRead\\\u0026#34;]).getTime()}}\u0026#34;, \u0026#34;value2\u0026#34;: \u0026#34;={{new Date($node[\\\u0026#34;RSS Feed Read\\\u0026#34;].data[\\\u0026#34;isoDate\\\u0026#34;]).getTime()}}\u0026#34; } ], \u0026#34;boolean\u0026#34;: [], \u0026#34;string\u0026#34;: [ { \u0026#34;value1\u0026#34;: \u0026#34;={{$json[\\\u0026#34;title\\\u0026#34;]}}\u0026#34;, \u0026#34;operation\u0026#34;: \u0026#34;contains\u0026#34; } ] } }, \u0026#34;name\u0026#34;: \u0026#34;IF\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;n8n-nodes-base.if\u0026#34;, \u0026#34;typeVersion\u0026#34;: 1, \u0026#34;position\u0026#34;: [ 560, 440 ] }, { \u0026#34;parameters\u0026#34;: { \u0026#34;functionCode\u0026#34;: \u0026#34;const staticData = this.getWorkflowStaticData(\u0026#39;global\u0026#39;);\\n\\nif (items.length \u0026gt; 0) {\\n staticData.latestRead = items[0].json.isoDate || staticData.latestRead;\\n}\\n\\n\\nreturn items;\u0026#34; }, \u0026#34;name\u0026#34;: \u0026#34;Write Latest Read\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;n8n-nodes-base.function\u0026#34;, \u0026#34;typeVersion\u0026#34;: 1, \u0026#34;position\u0026#34;: [ 760, 340 ] }, { \u0026#34;parameters\u0026#34;: {}, \u0026#34;name\u0026#34;: \u0026#34;NoOp\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;n8n-nodes-base.noOp\u0026#34;, \u0026#34;typeVersion\u0026#34;: 1, \u0026#34;position\u0026#34;: [ 750, 580 ] }, { \u0026#34;parameters\u0026#34;: { \u0026#34;triggerTimes\u0026#34;: { \u0026#34;item\u0026#34;: [ { \u0026#34;mode\u0026#34;: \u0026#34;everyX\u0026#34;, \u0026#34;value\u0026#34;: 1 } ] } }, \u0026#34;name\u0026#34;: \u0026#34;Cron\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;n8n-nodes-base.cron\u0026#34;, \u0026#34;typeVersion\u0026#34;: 1, \u0026#34;position\u0026#34;: [ -40, 440 ] }, { \u0026#34;parameters\u0026#34;: { \u0026#34;requestMethod\u0026#34;: \u0026#34;POST\u0026#34;, \u0026#34;options\u0026#34;: { \u0026#34;batchInterval\u0026#34;: 3000, \u0026#34;batchSize\u0026#34;: 1 }, \u0026#34;bodyParametersUi\u0026#34;: { \u0026#34;parameter\u0026#34;: [ { \u0026#34;name\u0026#34;: \u0026#34;msg_type\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;interactive\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;card\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;={\\n \\\u0026#34;config\\\u0026#34;: {\\n \\\u0026#34;wide_screen_mode\\\u0026#34;: true\\n },\\n \\\u0026#34;header\\\u0026#34;: {\\n \\\u0026#34;template\\\u0026#34;: \\\u0026#34;black\\\u0026#34;,\\n \\\u0026#34;title\\\u0026#34;: {\\n \\\u0026#34;content\\\u0026#34;: \\\u0026#34;{{$json[\\\u0026#34;title\\\u0026#34;]}}\\\u0026#34;,\\n \\\u0026#34;tag\\\u0026#34;: \\\u0026#34;plain_text\\\u0026#34;\\n }\\n },\\n \\\u0026#34;elements\\\u0026#34;: [\\n {\\n \\\u0026#34;tag\\\u0026#34;: \\\u0026#34;div\\\u0026#34;,\\n \\\u0026#34;text\\\u0026#34;: {\\n \\\u0026#34;content\\\u0026#34;: \\\u0026#34;{{$json[\\\u0026#34;contentSnippet\\\u0026#34;]}}\\\u0026#34;,\\n \\\u0026#34;tag\\\u0026#34;: \\\u0026#34;lark_md\\\u0026#34;\\n }\\n },\\n {\\n \\\u0026#34;tag\\\u0026#34;: \\\u0026#34;hr\\\u0026#34;\\n },\\n {\\n \\\u0026#34;elements\\\u0026#34;: [\\n {\\n \\\u0026#34;content\\\u0026#34;: \\\u0026#34;[阅读原文]({{$json[\\\u0026#34;link\\\u0026#34;]}})\\\u0026#34;,\\n \\\u0026#34;tag\\\u0026#34;: \\\u0026#34;lark_md\\\u0026#34;\\n }\\n ],\\n \\\u0026#34;tag\\\u0026#34;: \\\u0026#34;note\\\u0026#34;\\n }\\n ]\\n}\u0026#34; } ] }, \u0026#34;headerParametersUi\u0026#34;: { \u0026#34;parameter\u0026#34;: [ { \u0026#34;name\u0026#34;: \u0026#34;Content-Type\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;application/json\u0026#34; } ] } }, \u0026#34;name\u0026#34;: \u0026#34;HTTP Request\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;n8n-nodes-base.httpRequest\u0026#34;, \u0026#34;typeVersion\u0026#34;: 1, \u0026#34;position\u0026#34;: [ 1000, 340 ] }, { \u0026#34;parameters\u0026#34;: { \u0026#34;functionCode\u0026#34;: \u0026#34;const staticData = this.getWorkflowStaticData(\u0026#39;global\u0026#39;);\\n\\nlatestRead = staticData.latestRead;\\n\\nfor (let item of items) {\\n item.json.latestRead = latestRead || \u0026#39;2022-05-05\u0026#39;;\\n //item.json[\\\u0026#34;content:encodedSnippet\\\u0026#34;] = item.json[\\\u0026#34;content:encodedSnippet\\\u0026#34;].replace(/[\\\\r\\\\n]/g,\\\u0026#34;\\\\\\\\n\\\u0026#34;);\\n}\\n\\nreturn items;\u0026#34; }, \u0026#34;name\u0026#34;: \u0026#34;Latest Read\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;n8n-nodes-base.function\u0026#34;, \u0026#34;typeVersion\u0026#34;: 1, \u0026#34;position\u0026#34;: [ 360, 440 ] } ], \u0026#34;connections\u0026#34;: { \u0026#34;RSS Feed Read\u0026#34;: { \u0026#34;main\u0026#34;: [ [ { \u0026#34;node\u0026#34;: \u0026#34;Latest Read\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;main\u0026#34;, \u0026#34;index\u0026#34;: 0 } ] ] }, \u0026#34;IF\u0026#34;: { \u0026#34;main\u0026#34;: [ [ { \u0026#34;node\u0026#34;: \u0026#34;Write Latest Read\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;main\u0026#34;, \u0026#34;index\u0026#34;: 0 } ], [ { \u0026#34;node\u0026#34;: \u0026#34;NoOp\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;main\u0026#34;, \u0026#34;index\u0026#34;: 0 } ] ] }, \u0026#34;Write Latest Read\u0026#34;: { \u0026#34;main\u0026#34;: [ [ { \u0026#34;node\u0026#34;: \u0026#34;HTTP Request\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;main\u0026#34;, \u0026#34;index\u0026#34;: 0 } ] ] }, \u0026#34;Cron\u0026#34;: { \u0026#34;main\u0026#34;: [ [ { \u0026#34;node\u0026#34;: \u0026#34;RSS Feed Read\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;main\u0026#34;, \u0026#34;index\u0026#34;: 0 } ] ] }, \u0026#34;Latest Read\u0026#34;: { \u0026#34;main\u0026#34;: [ [ { \u0026#34;node\u0026#34;: \u0026#34;IF\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;main\u0026#34;, \u0026#34;index\u0026#34;: 0 } ] ] } } } 粘贴后可以看到如下的界面:\n这里有几处可以配置,第一处是 Cron,设置自动化流程触发的频率,每隔 X 时间间隔运行一次,图中设置为每隔一小时运行。在获取 RSS 时,运行频率不宜过高。如果访问过于频繁,一方面会给对方服务器造成较大负担,同时可能被服务器禁止访问。\n第二个是在 RSS Feed Read 处,填写想订阅的 RSS 地址,这里以少数派 RSS 为例,填写完后点击Excute node,先运行一次获取数据,方便后续设置。\n第三处(可选)IF 处,设置是否需要针对标题或内容等进行过滤,默认不过滤。\n这时先转到飞书,在飞书桌面端,打开一个群(建议先创建一个单人的群进行调试),打开设置,找到群机器人,并点击添加机器人,选择自定义机器人加入群聊,详细操作可以参照 飞书自定义机器人指南。\n最后在 HTTP Request 处填入飞书机器人 webhook 地址。\n填写完成后 Excute node 尝试运行,一切顺利的话就能在飞书中看到推送来的RSS消息了。\n这里使用了卡片的形式展示消息,若是想调整消息展示样式,可以参考少数派文章 手把手教你用飞书 Webhook 打造一个消息推送 Bot。\n一图流配置\n消息机器人安全设置 由于采用 Webhook 的形式,请务必保管好 Webhook 链接,如果泄露可能会导致被推送垃圾信息。为了进一步加道保险,飞书提供了三种安全设置方式,分别是自定义关键词、IP 白名单和签名校验。\n前两种方式非常好理解,也都很好设置。自定义关键词是只有当消息中至少含有一个预设的关键词时,才会进行消息推送;IP 白名单则是只推送名单中来源的 IP 所发送的请求。但是这两种方式也有一定的局限性:\n关键词有时使消息不够简洁 部署在本地树莓派等设备上时,IP 地址不固定,无法指定 关键词和 IP 白名单各自最多只能添加十个条目 因此这里详细介绍一下在 n8n 中进行签名校验的配置方式。\n飞书的签名需要将「timestamp + \u0026ldquo;\\n\u0026rdquo; + 密钥」组合起来当作签名密钥,采用 Hmac SHA256 算法计算签名,再进行 Base64 编码。在发送消息请求时,需要增加对应的timestamp和sign 字段。\n// 开启签名验证后发送文本消息的请求示例 { \u0026#34;timestamp\u0026#34;: \u0026#34;1599360473\u0026#34;, \u0026#34;sign\u0026#34;: \u0026#34;xxxxxxxxxxxxxxxxxxxxx\u0026#34;, \u0026#34;msg_type\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;content\u0026#34;: { \u0026#34;text\u0026#34;: \u0026#34;The message content is here\u0026#34; } } 在 n8n 中,可以使用 Crypto 模块利用密钥生成签名,复制以下代码粘贴到配置界面,可以得到生成飞书签名用的模块组合。\n{ \u0026#34;nodes\u0026#34;: [ { \u0026#34;parameters\u0026#34;: { \u0026#34;action\u0026#34;: \u0026#34;hmac\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;SHA256\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;={{\u0026#39;\u0026#39;}}\u0026#34;, \u0026#34;dataPropertyName\u0026#34;: \u0026#34;sign\u0026#34;, \u0026#34;secret\u0026#34;: \u0026#34;={{$json[\\\u0026#34;timestamp\\\u0026#34;]+\u0026#39;\\\\n\u0026#39;+$json[\\\u0026#34;secret\\\u0026#34;]}}\u0026#34;, \u0026#34;encoding\u0026#34;: \u0026#34;base64\u0026#34; }, \u0026#34;name\u0026#34;: \u0026#34;Crypto\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;n8n-nodes-base.crypto\u0026#34;, \u0026#34;typeVersion\u0026#34;: 1, \u0026#34;position\u0026#34;: [ -80, 440 ] }, { \u0026#34;parameters\u0026#34;: { \u0026#34;values\u0026#34;: { \u0026#34;string\u0026#34;: [ { \u0026#34;name\u0026#34;: \u0026#34;timestamp\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;={{Math.round(new Date().getTime()/1000)}}\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;secret\u0026#34; } ] }, \u0026#34;options\u0026#34;: {} }, \u0026#34;name\u0026#34;: \u0026#34;Set\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;n8n-nodes-base.set\u0026#34;, \u0026#34;typeVersion\u0026#34;: 1, \u0026#34;position\u0026#34;: [ -280, 440 ] } ], \u0026#34;connections\u0026#34;: { \u0026#34;Set\u0026#34;: { \u0026#34;main\u0026#34;: [ [ { \u0026#34;node\u0026#34;: \u0026#34;Crypto\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;main\u0026#34;, \u0026#34;index\u0026#34;: 0 } ] ] } } } 将上面新增的两个模块按下图方式进行拖拽连接:\n从飞书机器人设置界面中,勾选签名校验得到密钥,填写在 Set 模块中。\n接下来将 Latest Read 模块中的代码替换为以下内容,储存计算出的签名,方便在请求的时候调用。\n// JS code in the Latest Read Module const staticData = this.getWorkflowStaticData(\u0026#39;global\u0026#39;); latestRead = staticData.latestRead; for (let item of items) { item.json.latestRead = latestRead || \u0026#39;2022-05-05\u0026#39;; item.json.timestamp = $item(\u0026#34;0\u0026#34;).$node[\u0026#34;Crypto\u0026#34;].json[\u0026#34;timestamp\u0026#34;]; item.json.sign = $item(\u0026#34;0\u0026#34;).$node[\u0026#34;Crypto\u0026#34;].json[\u0026#34;sign\u0026#34;]; } return items; 最后在 HTTP Request 模块中增加校验用的字段:Body Parameters - Add Parameter,添加两个参数,Name 分别为 timestamp 和 sign,Value 处点击右侧 Add Expression,再分别点击选择传入的两个对应字段的值。\n这样一番倒腾,给飞书机器人模块增加了签名校验,使得信息推送更加安全。当一切配置妥当后,别忘了点击界面右上角的激活,让工作流开始自动运行。\n配置密钥验证一图流\n后记 本文介绍了如何用 n8n 打造一个飞书 RSS 推送机器人。订阅什么样的 RSS 来源,可以是网站自身提供的 RSS 地址,也可以利用 RSShub 将各种奇怪的网站转化为 RSS,甚至是利用 kill-the-newsletter 将任意 Newsletter 邮件转化为 RSS 进行追踪。\n同时,实现类似工作流的手段还有很多。对于 n8n 这部分,可以使用 IFTTT、Integrately,或是 Github Action 等,实现工作流中「监控 RSS 更新并发送 Webhook 请求」这部分;对于接收提醒,文中利用了飞书作为展示消息的界面,而 n8n 也支持连接到 Telegram、Slack 等通讯软件,或是通过 Send Email 模块实现邮件通知,以及发送到 Cubox、flomo 等各种支持 Webhook 的工具中。\n更多功能,更多组合,尽请探索,把闲置的云服务器或是积灰的树莓派等折腾起来吧。\n","permalink":"https://yorks0n.github.io/posts/use_n8n_to_build_feishu_rssbot/","summary":"本文介绍了基于 n8n 搭建的自动化平台,实现监控 RSS 更新并推送到飞书消息的功能。","title":"利用 n8n 打造飞书 RSS 推送机器人"},{"content":"注:本文首发于少数派,您可以 前往此处 阅读修订后版本。\n千变万化的「#」 当看到「#」时,你会想到什么?\n如果你下国际象棋,它可能代表着一局对决的终结1;如果你是程序员,它可能是被 #! 指定的解释器,或是一行注释的开始;如果你刷微博,它可能是当前最热的话题。中文里,「#」通常称为「井字」或「井号」,在日语中称为「番号记号」或「井桁」,英式英语中则通常称之为「hash」。\n「#」的大部分名称来源于其形状,含义却随着上下文发生变化。对大部分人而言,与「#」的第一次会面,大概是电话拨号盘角落中那个不起眼的方块。\nlibra pondo 的千年的漫步 先将时间拨回罗马时期,那时「一磅重」被称为「libra pondo」,其中 libra 意思是尺度或是平衡;pondo 则来自于动词 pendere,表示「称重」。从这两个词根中,「#」得到了它最早的形状与名称。\n十四世纪晚期,来源于 libra 的「lb」进入了英语中,同时配上了一条表明缩写的短线「~」,即 ℔。\n由于 ℔ 在当时的广泛使用,部分早期印刷机开始把它作为了一个单独的字符进行印刷。\n左图是 Isaac Newton 所写下的 ℔ 符号,右图是它出现在 1698 年印刷品中的样子。\n随着之后的发展,℔ 逐渐演变成了两个不同的形式:\n来源于抄写员潦草笔记的「#」 没有短线修饰代表磅的「lb」 而这个符号本身,却则淹没在时间长河中。\n与此同时,它的老搭档 pondo 也开始了独自的演变之路。它先以 pund 的形式出现在古英语中,又在现代英语中成为 pound。历经数千年,libra 与 pondo,这一对古老的搭档,最终又重新连接在一起。[^在美式英语中,# 被称为 pound sign]\n如果不是偶然的经历,也许「#」将一直存在于生活不起眼的角落,默默无闻地行使它最初的功能。\n拨号盘一隅 在电话出现的早期,拨号数字利用脉冲拨号(Pulse dialing)进行传输。在这种技术中,每个数字对应一到十次脉冲信号。上世纪40年代末,贝尔实验室发明了一种新的拨号系统。新系统在每个数字被按下的时候,发出一个独特的声音信号,被称为双音多频(Dual-Tone Multi-Frequency)。然而直到1968年,电话上的拨号键还只有 0-9 的按键。\n左图,早期使用脉冲拨号的转拨盘式电话;右图,贝尔实验室于 1963 年推出的世界第一台按键电话 WE 1500\n1968年,为了实现菜单选择等更多功能,贝尔实验室计划在数字 0 按键的两侧添加两个新的按键。在设计拨号盘新样式的过程中,曾诞生过一系列尝试性设计,比如在 0 的两侧分别增加带有五角星与菱形符号的按键。然而这些字符在当时标准的打字机键盘上并不存在,导致记录时会产生障碍。\n此时,负责新拨号系统设计的贝尔实验室的工程师 Douglas A. Kerr,被任命选择更加合适的符号替代它们。\nDouglas A. Kerr\nDouglas Kerr 曾经担任设计美国信息交换标准代码(ASCII)的委员会负责人。基于过去的工作经验,也考虑到打字机的键盘设计,他与团队最终选择了包含在 ASCII 字符集中的「*」与「#」作为新的按键符号。\n这个决定,使得「#」以前所未有的姿态进入了世界上绝大多数人的生活,它也将比历史上任何时候都更为人所熟悉。\n来「#」聊天吧 1988年,Jarkko Oikarinen 创建 Internet Relay Chat (IRC),这是一个基于文本的即时聊天系统。它被设计用于以组群的形式进行多人聊天,许多人可以加入同一个称为频道(channel)的组群中,频道的名称以「#」开头,用户可以用 /join #channelname 的方式加入某一个频道。\nIRC 客户端 HexChat 截图\n2007年,曾经在 Google 和 Uber 担任开发主管的 Chris Messina 在 Twitter 上提议,可以用一个类似的系统来标记网络上感兴趣的主题,并发出了第一条倡议使用「#标签」的推文。然而这一建议并没有立刻得到广泛认可,Twitter 联合创始人 Evan Williams 甚至告诉 Messina,这个概念永远都不会流行。\nMessina 没有放弃这个概念,他甚至写了一篇 Groups for Twitter; or A Proposal for Twitter Tag hannels 来详细阐释其使用方式。在当年的圣地亚哥大火期间,他联系了在 Twitter 上直播事件的加州居民 Nate Ritter,并建议后者在所有相关推文中带上 #SanDiegoFire 的标签。Twitter 这才逐渐认识到到这是对内容进行分组的有效方式。终于,2009 年 Twitter 官方将标签系统加入搜索工具中。次年,热门话题功能出现,将时下最流行的话题展示在所有用户面前。\n2014 年,牛津词典将其作为一个新的条目,添加到当年的更新中:\nhashtag n.(on social media web sites and applications) a word or phrase preceded by a hash and used to identify messages relating to a specific topic; (also) the hash symbol itself, when used in this way. 在推特等社交网络媒介中,出现在 # 符号后用来标注主题的词语。\n「#」的今天与明天 如今,「#」已经很少用来表示重量,也只有偶然间才在通话时被按下,但它依旧活跃在互联网弄潮儿的指尖。如果要用一个词形容现在的它,那或许是「主题」。在用 Markdown 写作时,它界定着层级的标题,在文章开头结尾打下标签,以最简洁的方式描述着文章的主题;在媒体上,一个个标签引导着时下最流行的趋势,却也在看不见的地方暗流涌动。相同的标签,连接不同的内容,把彼此独立的信息编织成网,同一个标签下,聚集着相似的人们。那么,是否一切都可以打上标签?标签网络之中,是否也隐藏着我们的未来?\nGoogle Ngram 统计的「#」在 1800-2019 年英文文献中出现的频率\n在你眼中,「#」代表什么?\n图片来源 https://www.newyorker.com/books/page-turner/the-ancient-roots-of-punctuation\nhttps://www.smashingmagazine.com/2016/01/why-i-moved-from-a-square-to-a-circle-calculator-interface-design/\nhttps://zh.m.wikipedia.org/zh-hans/脉冲拨号\nhttp://dougkerr.net/Pumpkin/AboutAuthor.htm\n参考资料 Shady Characters : the Secret Life of Punctuation, Symbols, \u0026amp; Other Typographical Marks Hashtag History: From Typewriters to Twitter Trends Hashtag - Wikipedia \u0026#160;\u0026#x21a9;\u0026#xfe0e; ","permalink":"https://yorks0n.github.io/posts/history_of_hash/","summary":"当看到「#」时,你会想到什么?","title":"「#」的前世今生"},{"content":"前言 这是一篇关于数字健康的文章,旨在探讨为什么会对低效率产生恐惧,这种恐惧会带来什么影响,以及如何缓和这种恐惧。\n本文并非要倡导停止追求高效,也不是否定优秀工具的重要性,而是希望大部分只是希望利用工具辅助完成任务的人,不要过分纠结于寻求完美的工具和高效的方法,却反倒影响了工作目标的实现。\n好工具,低生产力 在赛博朋克主题的作品中,存在一种科学技术高度发达,但是底层人民的生活水平并没有随之提高的现象,被称为『高科技,低生活』。与之相似,我们现在的工作过程也存在一种现象:软件功能愈发齐全,技术方法百花齐放,但我们的生产力并不一定随之提高。\n产生这种现象的原因之一,是我们在努力提高效率的过程中,错把追求高效本身当作了我们的目标,而不是我们实现目标的手段。\n对低效率的恐惧使效率成为目标 类似错失恐惧症(fear of missing out, FOMO),一种担心自己错过可以改善生活的信息、经历的感觉,现在也有一种可称为**低效率恐惧(fear of low efficiency, FOLE)**的现象,又称生产力色情或是效率成瘾。我们担心浪费任何时间,沉迷于优化自己花费时间的方式,然而实际的产出却寥寥无几。这种恐惧甚至会妨碍我们完成重要的事本身,我自己就曾在写作时纠结过是否用了最好的写作软件,在做笔记时担心是否采用了最先进的笔记技巧,而不是专心在自己的内容上。\n正如其他成瘾现象都基于某种奖赏机制,低效率恐惧可能也源于高生产力带来的正向反馈。提高生产力通常能带来直接的好处,比如产出增加或收入提高,这种反馈不断正向强化我们的行为,最终使效率在不经意间成为了我们的目标。\n低效率恐惧可能还源于消费主义试图消费一切的动机。为了促进销售,商家贩卖焦虑,其中也有一种对低效率的焦虑。商家将购买某个工具或某门课程,与高效之间画了连线,给人植入『使用了这个软件,学了这门课程,你就能变得和效率达人一样高效』的印象。我们的消费欲望,来源于我们对想成为的人(idol)的模仿欲。我们期待通过与效率达人们使用相似的工具,模仿他们的工作流程,变得像他们一样高效且成果斐然。\n另一方面,低效率恐惧也是一种拖延的表现。当我们不想工作时,列计划或是阅读提高工作效率的文章,实际上充当了感觉上的替代品。在我们逃避真正工作的同时,给了我们正在从事产出的错觉。\n将效率作为目标会引起哪些问题 效率工具是辅助我们完成任务的手段,完成工作才是真正的目的,但在追求高效的过程中很容易将手段与目的混淆。如果花费过多本属于工作和生活的时间追求效率,整天忙忙碌碌,最终发现产出却寥寥无几,平添焦虑的同时效率不升反降。\n不论技术怎样进步,软件和算法都只能按照它们设计出来的方式运行,它们不能替我们做出决定,也无法承担责任。使用合适的工具可以帮助我们工作,追求完美的工具则是一种猎奇。就像机械键盘,有人花数百上千组装自己的键盘,已经不再只是为了用键盘实现打字的目的,而是把折腾它的过程作为一种乐趣了。\n对错过新工具、新技术的焦虑同样会导致沉迷于用即时的短期满足来缓解焦虑,比如不停地钻研各种效率文章,将工具一个个进行试用比较,甚至可能因为害怕错过提升效率,去参加一些我们并不真正需要的活动,例如报名我们用不上的学习课程。学会了屠龙之技,失去的是本当用于工作的时间,错过的则是我们自己的生活。\n如何缓解低效率恐惧 确定自己关注的主题和领域 知识浩如烟海,如果不清楚自己真正关注什么,便无法针对性地进行积累。如同在海上航行却没有目标,如果不论遇到什么都囫囵地装进口袋,最终得到的只有乱糟糟的收藏夹,并不会促进实质性的能力提升。这里推荐少楠的《P.A.R.A.》方法,将自己所有关注的内容划分成领域、项目、资源等方面。**领域(Area)**是自己日常需要精进的方面,如果搞砸了需要承担对应的责任;**项目(Project)**有明确的起止时间和目标;**资源(Resource)**是自己持续感兴趣,但哪怕放弃,也不会影响他人的事。具体如何实践,可以进一步阅读少楠的文章不知道积累什么知识,是因为你没有自己关注的领域。\n反思对效率工具的使用,识别真正的限制因素 回顾自己使用了哪些效率工具,如何使用,是否朝着自己关注的领域与设定的长期计划前进。当我们做计划或是研究效率技巧的时候,我们是希望籍此辅助自己完成工作,还是在逃避推进工作。识别哪些因素真正妨碍了我们的工作,是工具或者生产力系统的缺陷吗?虽然各种算法和工具可以辅助我们进行思考和决策,但不能依赖工具而忽略了我们自身应当承担的责任。我们记下了许多笔记,但是再好的软件也不能替代我们理解和运用这些知识;相反,如果我们积极地应用这些知识,哪怕手中只有纸笔,也能非常好地掌握知识。\n停止盲目收集,调整信息来源 留意信息的输入途径,如果使用收集箱inbox的形式,让自己的列表中放更多对自己关注的项目/领域/资源有帮助的内容。有些文章当下感到值得一读,便放进了收集箱,过一阵子再看到时觉得读它可有可无,那就应当果断将其删掉,并非一定放进收集箱的东西都非得读完。\n重器轻用,建立适合自己的工作流 与其不断搜寻可以提高生产力的技巧,阅读如何做笔记的文章,不如确定一个适合我们的系统并稳定地使用它。Kenshin在重器轻用就是高效的文章中提到,许多人纠结于选择哪个笔记工具,是因为试图在某一个工具中实现All-in-One,并以为这样就能达到简单高效。然而没有完全满足用户需求的工具存在,因此应当重器轻用,发挥各个工具的长处。Spike112也在其文章工作流的祛魅中指出,在永无止境的探索过程中,新旧工具的迁移消耗了我们大量的时间和精力,应当根据场景识别需求而选择工具,而不是根据某个工具的功能去寻找它的使用场景。这篇文章中也提出,工作流比工具重要,而实践又比工作流和工具更重要,因为真正有用的工作流,是在实践的过程中不断升级优化产生的。就像只有自己整理房间,才更清楚每个工具放在哪里,也只有在整理的过程中,才能思考诸如如何优化工作环境的问题,让自己在之后的工作中更加顺手。\n专注于我们关注的内容本身 关注内容本身,而非如何获取、储存这些内容。花更多的时间与我们收集到的内容呆在一起,思考如何使用它们,而非利用一系列自动化流程将笔记碎片积累到数据库后,囤积在那再也不看。乍看之下,笔记本中满满的笔记摘录很有成就感,但如果从此不再使用,笔记本只能成为笔记的坟场。问一问自己,我积累了这么多的笔记,然后呢?思考我们为什么要记笔记,是为了更好地理解某个概念,学习新领域的知识,通过笔记辅助我们思考和写作,亦或只是为了把玩某种先进的笔记技巧?为自己收集的内容找一个出口,比如写作,将死气沉沉的笔记调动起来,在输出的过程中厘清思路,进而更好地掌握输入的内容。\n刻意花一些时间远离网络 网络上信息无穷无尽,作为个人不可能将其全部吸收。短时间大量的信息输入会助长失控感,引起焦虑。不妨花些时间独自思考,阅读,散步,健身,做些让自己感到放松舒适的事。生活不只有高效的工作,只有保持克制,接受自己和工具的不完美,才能重新出发,以更好的节奏投入新的工作。\n接受系统和工具的不完美,真正重要的是我们做的事本身。\n最后,感谢您的阅读。\n参考资料 放弃纠结、拥抱妥协,重器轻用就是高效 年度征文 | 我是如何艰难地克服「效率成瘾」的? 工作流的祛魅:从工具、阅读到写作 收藏≠学会,别再让你的收藏夹吃灰了! Automations, Time spent in the environment, \u0026ldquo;And then what?\u0026rdquo; From FOMO to JOMO: the joy of missing out Productivity addiction: when we become obsessed with productivity ","permalink":"https://yorks0n.github.io/posts/efficiency_and_life_balance/","summary":"\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e这是一篇关于数字健康的文章,旨在探讨为什么会对低效率产生恐惧,这种恐惧会带来什么影响,以及如何缓和这种恐惧。\u003c/p\u003e\n\u003cp\u003e本文并非要倡导停止追求高效,也不是否定优秀工具的重要性,而是希望大部分只是希望利用工具辅助完成任务的人,不要过分纠结于寻求完美的工具和高效的方法,却反倒影响了工作目标的实现。\u003c/p\u003e\n\u003ch2 id=\"好工具低生产力\"\u003e好工具,低生产力\u003c/h2\u003e\n\u003cp\u003e在赛博朋克主题的作品中,存在一种科学技术高度发达,但是底层人民的生活水平并没有随之提高的现象,被称为『高科技,低生活』。与之相似,我们现在的工作过程也存在一种现象:软件功能愈发齐全,技术方法百花齐放,但我们的生产力并不一定随之提高。\u003c/p\u003e\n\u003cp\u003e产生这种现象的原因之一,是我们在努力提高效率的过程中,错把追求高效本身当作了我们的目标,而不是我们实现目标的手段。\u003c/p\u003e\n\u003ch2 id=\"对低效率的恐惧使效率成为目标\"\u003e对低效率的恐惧使效率成为目标\u003c/h2\u003e\n\u003cp\u003e类似错失恐惧症(fear of missing out, FOMO),一种担心自己错过可以改善生活的信息、经历的感觉,现在也有一种可称为**低效率恐惧(fear of low efficiency, FOLE)**的现象,又称生产力色情或是效率成瘾。我们担心浪费任何时间,沉迷于优化自己花费时间的方式,然而实际的产出却寥寥无几。这种恐惧甚至会妨碍我们完成重要的事本身,我自己就曾在写作时纠结过是否用了最好的写作软件,在做笔记时担心是否采用了最先进的笔记技巧,而不是专心在自己的内容上。\u003c/p\u003e\n\u003cp\u003e正如其他成瘾现象都基于某种奖赏机制,\u003cstrong\u003e低效率恐惧可能也源于高生产力带来的正向反馈\u003c/strong\u003e。提高生产力通常能带来直接的好处,比如产出增加或收入提高,这种反馈不断正向强化我们的行为,最终使效率在不经意间成为了我们的目标。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e低效率恐惧可能还源于消费主义试图消费一切的动机\u003c/strong\u003e。为了促进销售,商家贩卖焦虑,其中也有一种对低效率的焦虑。商家将购买某个工具或某门课程,与高效之间画了连线,给人植入『使用了这个软件,学了这门课程,你就能变得和效率达人一样高效』的印象。我们的消费欲望,来源于我们对想成为的人(idol)的模仿欲。我们期待通过与效率达人们使用相似的工具,模仿他们的工作流程,变得像他们一样高效且成果斐然。\u003c/p\u003e\n\u003cp\u003e另一方面,\u003cstrong\u003e低效率恐惧也是一种拖延的表现\u003c/strong\u003e。当我们不想工作时,列计划或是阅读提高工作效率的文章,实际上充当了感觉上的替代品。在我们逃避真正工作的同时,给了我们正在从事产出的错觉。\u003c/p\u003e\n\u003ch2 id=\"将效率作为目标会引起哪些问题\"\u003e将效率作为目标会引起哪些问题\u003c/h2\u003e\n\u003cp\u003e效率工具是辅助我们完成任务的手段,完成工作才是真正的目的,但在追求高效的过程中很容易将手段与目的混淆。如果花费过多本属于工作和生活的时间追求效率,整天忙忙碌碌,最终发现产出却寥寥无几,\u003cstrong\u003e平添焦虑的同时效率不升反降\u003c/strong\u003e。\u003c/p\u003e\n\u003cp\u003e不论技术怎样进步,软件和算法都只能按照它们设计出来的方式运行,它们不能替我们做出决定,也无法承担责任。\u003cstrong\u003e使用合适的工具可以帮助我们工作,追求完美的工具则是一种猎奇\u003c/strong\u003e。就像机械键盘,有人花数百上千组装自己的键盘,已经不再只是为了用键盘实现打字的目的,而是把折腾它的过程作为一种乐趣了。\u003c/p\u003e\n\u003cp\u003e对错过新工具、新技术的焦虑同样会导致沉迷于用即时的短期满足来缓解焦虑,比如不停地钻研各种效率文章,将工具一个个进行试用比较,甚至可能因为害怕错过提升效率,去参加一些我们并不真正需要的活动,例如报名我们用不上的学习课程。学会了屠龙之技,\u003cstrong\u003e失去的是本当用于工作的时间,错过的则是我们自己的生活\u003c/strong\u003e。\u003c/p\u003e\n\u003ch2 id=\"如何缓解低效率恐惧\"\u003e如何缓解低效率恐惧\u003c/h2\u003e\n\u003ch3 id=\"确定自己关注的主题和领域\"\u003e确定自己关注的主题和领域\u003c/h3\u003e\n\u003cp\u003e知识浩如烟海,如果不清楚自己真正关注什么,便无法针对性地进行积累。如同在海上航行却没有目标,如果不论遇到什么都囫囵地装进口袋,最终得到的只有乱糟糟的收藏夹,并不会促进实质性的能力提升。这里推荐少楠的《P.A.R.A.》方法,将自己所有关注的内容划分成领域、项目、资源等方面。**领域(Area)**是自己日常需要精进的方面,如果搞砸了需要承担对应的责任;**项目(Project)**有明确的起止时间和目标;**资源(Resource)**是自己持续感兴趣,但哪怕放弃,也不会影响他人的事。具体如何实践,可以进一步阅读少楠的文章\u003ca href=\"https://mp.weixin.qq.com/s?__biz=MzI0MDA3MjQ2Mg==\u0026amp;mid=2247485941\u0026amp;idx=1\u0026amp;sn=28e92a5f06fb1883e95d6dc14db63d5d\u0026amp;chksm=e9212b94de56a2824cd58114927e2011d71e89b85358bf973c3ba50449ca0eb398b4fa254d55\u0026amp;mpshare=1\u0026amp;scene=1\u0026amp;srcid=0512NCDIBaqvdu4CXusvsg2l\u0026amp;sharer_sharetime=1652338328485\u0026amp;sharer_shareid=6d6f8a7d66e79b9e6c40cbf64b5690df#rd\"\u003e不知道积累什么知识,是因为你没有自己关注的领域\u003c/a\u003e。\u003c/p\u003e\n\u003ch3 id=\"反思对效率工具的使用识别真正的限制因素\"\u003e反思对效率工具的使用,识别真正的限制因素\u003c/h3\u003e\n\u003cp\u003e回顾自己使用了哪些效率工具,如何使用,是否朝着自己关注的领域与设定的长期计划前进。当我们做计划或是研究效率技巧的时候,我们是希望籍此辅助自己完成工作,还是在逃避推进工作。识别哪些因素真正妨碍了我们的工作,是工具或者生产力系统的缺陷吗?虽然各种算法和工具可以辅助我们进行思考和决策,但不能依赖工具而忽略了我们自身应当承担的责任。我们记下了许多笔记,但是再好的软件也不能替代我们理解和运用这些知识;相反,如果我们积极地应用这些知识,哪怕手中只有纸笔,也能非常好地掌握知识。\u003c/p\u003e\n\u003ch3 id=\"停止盲目收集调整信息来源\"\u003e停止盲目收集,调整信息来源\u003c/h3\u003e\n\u003cp\u003e留意信息的输入途径,如果使用收集箱inbox的形式,让自己的列表中放更多对自己关注的项目/领域/资源有帮助的内容。有些文章当下感到值得一读,便放进了收集箱,过一阵子再看到时觉得读它可有可无,那就应当果断将其删掉,并非一定放进收集箱的东西都非得读完。\u003c/p\u003e\n\u003ch3 id=\"重器轻用建立适合自己的工作流\"\u003e重器轻用,建立适合自己的工作流\u003c/h3\u003e\n\u003cp\u003e与其不断搜寻可以提高生产力的技巧,阅读如何做笔记的文章,不如确定一个适合我们的系统并稳定地使用它。Kenshin在\u003ca href=\"https://sspai.com/post/71576\"\u003e重器轻用就是高效\u003c/a\u003e的文章中提到,许多人纠结于选择哪个笔记工具,是因为试图在某一个工具中实现All-in-One,并以为这样就能达到简单高效。然而没有完全满足用户需求的工具存在,因此应当重器轻用,发挥各个工具的长处。Spike112也在其文章\u003ca href=\"https://sspai.com/post/71658\"\u003e工作流的祛魅\u003c/a\u003e中指出,在永无止境的探索过程中,新旧工具的迁移消耗了我们大量的时间和精力,应当根据场景识别需求而选择工具,而不是根据某个工具的功能去寻找它的使用场景。这篇文章中也提出,工作流比工具重要,而实践又比工作流和工具更重要,因为真正有用的工作流,是在实践的过程中不断升级优化产生的。就像只有自己整理房间,才更清楚每个工具放在哪里,也只有在整理的过程中,才能思考诸如如何优化工作环境的问题,让自己在之后的工作中更加顺手。\u003c/p\u003e\n\u003ch3 id=\"专注于我们关注的内容本身\"\u003e专注于我们关注的内容本身\u003c/h3\u003e\n\u003cp\u003e关注内容本身,而非如何获取、储存这些内容。花更多的时间与我们收集到的内容呆在一起,思考如何使用它们,而非利用一系列自动化流程将笔记碎片积累到数据库后,囤积在那再也不看。乍看之下,笔记本中满满的笔记摘录很有成就感,但如果从此不再使用,笔记本只能成为笔记的坟场。问一问自己,我积累了这么多的笔记,然后呢?思考我们为什么要记笔记,是为了更好地理解某个概念,学习新领域的知识,通过笔记辅助我们思考和写作,亦或只是为了把玩某种先进的笔记技巧?为自己收集的内容找一个出口,比如写作,将死气沉沉的笔记调动起来,在输出的过程中厘清思路,进而更好地掌握输入的内容。\u003c/p\u003e\n\u003ch3 id=\"刻意花一些时间远离网络\"\u003e刻意花一些时间远离网络\u003c/h3\u003e\n\u003cp\u003e网络上信息无穷无尽,作为个人不可能将其全部吸收。短时间大量的信息输入会助长失控感,引起焦虑。不妨花些时间独自思考,阅读,散步,健身,做些让自己感到放松舒适的事。生活不只有高效的工作,只有保持克制,接受自己和工具的不完美,才能重新出发,以更好的节奏投入新的工作。\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e接受系统和工具的不完美,真正重要的是我们做的事本身。\u003c/p\u003e\u003c/blockquote\u003e\n\u003cp\u003e最后,感谢您的阅读。\u003c/p\u003e\n\u003ch2 id=\"参考资料\"\u003e参考资料\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://sspai.com/post/71576\"\u003e放弃纠结、拥抱妥协,重器轻用就是高效\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://sspai.com/post/71518\"\u003e年度征文 | 我是如何艰难地克服「效率成瘾」的?\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://sspai.com/post/71658\"\u003e工作流的祛魅:从工具、阅读到写作\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://sspai.com/post/72939\"\u003e收藏≠学会,别再让你的收藏夹吃灰了!\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://buttondown.email/jessmartin/archive/time-spent-in-the-environment-and-then-what/\"\u003eAutomations, Time spent in the environment, \u0026ldquo;And then what?\u0026rdquo;\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://nesslabs.com/jomo\"\u003eFrom FOMO to JOMO: the joy of missing out\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://nesslabs.com/productivity-addiction\"\u003eProductivity addiction: when we become obsessed with productivity\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e","title":"克服低效率恐惧,回归健康生活"},{"content":"本文参考了 Nature、Science、Plant Cell 等期刊的图片指南整理而成,旨在介绍一些作图前后会遇到的基本概念及要求。应注意的是,本文只能作为参考,具体的作图要求会依据期刊发生变化,应遵循期刊提供的投稿指南。\n科研论文绘图的特点 相比于文字描述,论文中的图表通常是最快传递大量复杂信息的手段。\n高质量的图片结果会传递出专业性,给读者良好的第一印象 许多人在阅读时也会从图片开始,因此应保证图片清晰准确地传递信息 图片也是吸引读者进一步阅读文章内容的基础,因此条件允许时适当兼顾艺术性 本文包含什么 本文包含许多在作图前后,尤其是完成单张结果图后,进行进一步图片组合时所需了解的基本概念与注意事项。\n本文不包含什么 本文不是指导投稿某个期刊时的作图规范,一切具体标准与要求仍以各期刊自己的投稿指南为准。\n创建画布 图片格式 图片格式可以分成位图与矢量图两种:\n位图(Bitmap),又称栅格图(Raster graphics),指使用像素点组成的阵列来表示的图像,通过定义每个像素点的位置及其颜色来生成图片,比如JPG、TIFF等。 矢量图(Vector)是用点、直线或多边形等基于数学方程的几何元素表示的图像,如PDF、EPS等。\n由于矢量图记录的是形状的计算方式,其经过放大也不会变得模糊,因此是作图时首选的图片格式。\n期刊主要接受的位图格式为TIFF,接受PDF等矢量图;其中PDF中可以同时储存位图与矢量图,因而成为更加通用的格式;尽量避免使用PowerPoint储存图像。\n画布尺寸 由于出版时版面宽度限制,期刊通常会对图片的尺寸有所要求,为了更好地排列每张Figure中的图片大小及位置,同时匹配字号和图片尺寸,最好在新建画布时就设定好尺寸。\n每个期刊对于图片尺寸的要求各不相同,一般会区分单栏或双栏的布局方式。 部分期刊的图片尺寸要求如下:\n期刊 单栏(cm) 双栏(cm) Nature 9 18 Plant Cell 8.25 16.5 Science 5.5 12 图片的高度一般没有明确要求,PC建议最大图片高度20 cm,Nature建议最大图片高度17 cm,以尽量保证图片和图例在同一页范围内。\n颜色模式 颜色模式是数字图像中表示颜色的算法,期刊中常见要求有RGB模式与CMYK模式。 RGB模式:利用红(R)、绿(G)、蓝(B)三种颜色的加法混合,产生各种各样的颜色。 CMYK模式:将三原色叠加生成的四种颜色,即青色(C)、洋红色(M)、黄色(Y)与黑色(K),利用减法混合,形成CMYK颜色。 不同期刊对于投稿图片中的颜色模式的要求也各有不同,比如Science要求CMYK,Plant Cell则要求RGB。 不用担心,这两种颜色模式可以相互转换,但每次都会损失一点数据,所以最好先用RGB处理好图像,一旦有需要,再将其转换为CMYK模式。\n字体 衬线,是指笔画末端的装饰线,是区分不同英文字体最显著的特征。有衬线的字体叫做衬线字体(Serif),而没有的则是非衬线(Sans-Serif)。(「Serif」意为「衬线」,「Sans」在法文中意为「没有」) 常见期刊一般要求使用非衬线字体,如Arial或Helvetica,且不同期刊对于图片中的字体大小也有要求:\n期刊 最小字号(pt) 最大字号(pt) Nature 5 7 Science 5 7 Plant Cell 6 8 要注意的是组合多张图片时,通常图片会被缩放,这时实际显示出的字号会发生变化,应以最终缩放后的字号为准;多张图片的标注(即标注 A, B, C, D 时),应采用大写加粗,具体字号另各有要求。\n颜色 图片中的颜色应当差异明显且视觉效果良好。期刊都会要求考虑到色觉障碍人士,因而要求避免使用诸如红色与绿色这样的颜色组合作为对比(改为使用洋红色与绿色),尤其是在荧光显微照片中。 分辨率 在涉及到位图的时候,就要考虑分辨率,通常以ppi作为单位(pixels per inch)。分辨率过低会导致图片在放大时边缘模糊。 在纯线条与文字组成的图片中(如化学式),分辨率尤其重要。一个好的方法是将图片放大至400%(至少200%),观察其边缘是否依然锐利清晰。 纯矢量图不需要考虑分辨率;如果导出位图则照片尽量达到300 ppi。\n图片布局 一大原则就是避免空间浪费,但应保证不同的照片边缘有明显分界线;同时图片边缘尽量对齐。\n额外注意事项 务必整理好所有作图过程中使用过的原始图片,尽量保证其分辨率,最好是原始格式的原始文件,因为部分杂志会要求提供原始图片。\n相比于文中提到的要求,不同期刊对于图片都会有各自的额外要求,一切应以期刊提供的投稿指南为准。比如Nature要求所有图片中的文字可编辑;Science要求避免使用灰度图等。\n推荐进一步阅读Plant Cell提供的Detailed Figure Guidelines,里面不但有杂志自身的投稿要求,还对许多基本概念有详细介绍,同时对一些可能犯的错误提供了修改意见。\nReferences 位图与矢量图: https://business.oregonstate.edu/student-experience/resources/DAMlab/vector-and-bitmap-image-guide RGB模式与CMYK模式: https://99designs.ca/blog/tips/correct-file-formats-rgb-and-cmyk/ Nature: https://www.nature.com/nature/for-authors/initial-submission Science: https://www.science.org/content/page/instructions-preparing-initial-manuscript Plant Cell: https://academic.oup.com/plcell/pages/general-instructions Figures and tables - springer: https://www.springer.com/gp/authors-editors/authorandreviewertutorials/writing-a-journal-manuscript/figures-and-tables/10285530 ","permalink":"https://yorks0n.github.io/posts/basic-about-paper-figures/","summary":"参考几个期刊的投稿指南,整理了一些论文作图时会遇到的基本概念及要求。","title":"科研论文作图基本知识"},{"content":"最近读完了 Daniel T. Willingham 所写的《为什么学生不喜欢上学?》。这是介绍教育原理的书,旨在给教师提供教学意见。其中的许多内容直观地解释了「学习」这个过程中所运用到的「认知原理」。我们自然没有提升教学水平的任务,但它同样能为我们学习或向他人有效传递信息提供参考。\n认知原理 全书共提到了9个认知原理,分别是:\n人类具有好奇心,但大脑会尽力避免思考 事实性的知识先于技能 记忆是思考的残留物 我们依靠已知内容理解新的内容 练习才能熟练掌握 学习早期的认知力与晚期的截然不同 学生在学习方面相似多过差异 学生智力上的差异可以通过更持久的努力改变 教学水平也需要通过练习提高 此处并不期待制作出这本书的知识总结,而是摘取部分我觉得较为实用的要点进行回顾。\n我们如何思考 下图是一张简化的大脑运作模型,我们从环境(外部信息源)获取信息进入工作记忆(工作区),利用工作记忆进行思考;我们还会从长期记忆(内部信息源)提取与工作相关的信息到工作区,协助处理信息。工作记忆的空间有限,且没有什么已知的好办法扩展它。一旦工作记忆变得过于拥挤,思考就会异常艰难。因此,思考的成功取决于四个方面:\n环境中的信息 长期记忆中的信息 长期记忆中的步骤 工作记忆的空间大小 简化的大脑运作模式图\n工作记忆的空间大小不是由内容的文字多少决定,而是由有意义的片段决定\n长期记忆中的背景知识可以帮助把大块的内容合并成有意义的信息单元\n背景知识使合并成为可能,它使得片段间的联系变得容易,提高了工作记忆的空间利用效率,最终使理解变得容易。\n只有好奇并不使人思考 这并不是说好奇不重要,好奇心依然是我们最好的老师。大脑天生懒惰,当我们能侥幸通过某种方式完成任务时,便不会再去积极思考,反而会依赖记忆,在下次任务出现时依照记忆行动。思考的过程耗费相当的精力,只有当我们明白解决某一问题后会带来愉悦感时,我们才会喜欢思考。太过简单或太过困难的问题都不会让人开心,因此只有恰当地依照对方的背景知识,提出合适的问题,才能促成对方积极思考。\n背景知识帮助我们思考 思考是以新的方式组合信息,这既包含随时可以从外部查询的信息,又包含长期记忆中的信息。外界直接获取的信息储存在短期的工作记忆中。我们熟悉的信息不会占用太多工作记忆,因为大脑可以根据长期记忆将信息组合成新的单元进行暂时存放;不熟悉的新内容则会占据大量工作记忆,导致难以思考。但如果能在查找时,将新获得的信息与之前的信息建立关联,可以帮助记忆,减少在工作记忆的空间占用。\n背景信息还帮助我们进行交流。在与他人沟通时,为了避免过度冗长,我们通常会适当省略一些信息。事无巨细将每个细节讲出来会导致啰嗦,也会令听者失去耐心;相反,如果过度省略信息,在双方知识不对等的情况下,会导致无法互相理解,反而加剧交流障碍。\n记忆是思考的残留 如果我们仔细地思考过一件事情,就更有可能之后再次想起它,思考让大脑明白某件事是应该被存储的。记忆不是我们想要记住或尝试记住的事,记忆是我们所思考的事。\n我们在已知的环境中理解新事物 学习知识的过程在于用相关联的事实来解释一个中心概念,而不是建立事实性的知识点清单。思考的过程就是在为知识点建立联系,这与记住知识点本身同样重要;理解一个新的概念就是让恰当的已有概念进入工作记忆,并加以重新组合,因此理解其实就是记忆。\n可以通过类比等方法帮助理解抽象的概念,但类比也需要恰当地选择例子,如果受众对于例子过于不了解,那么此类比也难以帮助其理解问题。\n一个问题通常具有表层结构和深层结构。表层的结构是直观的,但对于解决问题可能帮助不大;正确辨别问题的深层结构有助于解决问题,然而一个问题可能有多种深层结构,因而难以正确处理它。\n将抽象概念利用类比转化成一个具象事件的过程,实际上是在把问题的深层结构与一个好理解的表层结构建立联系。\n何为「表层结构」与「深层结构」:以小学奥数题为例,一个水池一边排水一边进水,问多久水池能装满。如果只看到表层结构中的水池、水龙头,是不会将它与先前例题中牛吃草的吃草速度、牧草生长速度联系起来的;而这个问题的深层结构是「速度差」,即进水与排水的速度差,或是吃草与长草的速度差,只有把握了这一深层结构,才能解决这一类而非这一个具体的问题;因为表层结构是多变的,而深层结构间可能有共通之处。\n因此在不能把问题正确地由表层结构连结到恰当的深层结构上时,便无法利用已有知识解决问题。\n通过接触更多例子,或是比较不同的例子,可以帮助我们建立对深层结构(抽象概念)的理解,此即练习的作用。\n练习,还是练习 练习使得在进行底层的基础过程时,得以不假思索,为更高级更深入的过程提供思考所需的空间;不恰当的练习设计会磨灭积极性,所以需要恰当选择练习的内容与形式。\n何为「基础过程」:所谓基础也就是人在某一个领域一遍又一遍重复的事情,通过练习使其达到自动化,它们为日后更高级的工作奠定了基础。例如乒乓球员练习发球,通过练习使其几乎不占用额外的精力,让注意力得以更多地转移到比赛的其他过程。\n由于工作空间区域有限且无法通过某种方式扩展,因此就得:\n采取某种方式压缩其中的内容 提高工作记忆中操纵信息的效率 实际上这两者都是从长期记忆中提取一部分到工作区中,因此只占用工作区内的一小部分。\n练习可以使记忆更长久,而分散练习有助于记忆维持更长的时间,同时让学生有更多的机会思考如何将学到的东西加以应用,即练习如何将问题与恰当的知识点建立联系的过程。要达到自动化需要很多练习,最好的办法是既分散联系的时间,又分散练习的环境,尽量多设计有创意的方法来练习最关键的技巧,使得能够在更高阶的环境中学到基本技能。\n一些额外的建议 与人搭档合作,一同学习是个好办法。\n但除非被问及,否则不要建议别人该做什么。你不会希望做一个什么都懂的圣人。如果你的搭档想咨询你的建议,他会来问你的,这时候你当然可以畅所欲言了。但是在他问你之前,当好一个谨慎的、支持的旁观者,不要以为自己是万能的协调者,不管你多有信心、解决方法多好都不要插手。\n参考资料 为什么学生不喜欢上学?\n","permalink":"https://yorks0n.github.io/posts/why_dont_we_love_study/","summary":"读书笔记 ——《为什么学生不喜欢上学?》","title":"为什么我们不喜欢学习"}]