Yihui Xie

叶翔

谢益辉 / 2017-10-03


我在继续执行我的退出微信计划,不过昨天我在 COS 八卦群里破了两次例。一次是因为叶翔提了一个问题,其中有三点让我感到非常满意,所以我冒泡出来回答了一下。这三点分别是:

  1. 他说他为了不干扰群里的信息流,所以把问题制成了一张单独的图片发出来1。这样占用的视觉空间会小一些,不感兴趣的人不会受到太大的视觉干扰。我觉得他很用心而且很体谅人。微信群的信息混乱问题一直是我吐槽的重点。不过我要重申一下我的观点:微信随意聊天唠嗑,我觉得一点问题都没有,双手赞成;讨论正事?别介。叶翔的这个做法让我深深感到他非常尊重公共秩序,这会唤起我强烈的同情心,让我愿意花时间仔细琢磨他的问题。

  2. 他的问题里仔细说明了他的失败尝试。显然,他不是那种斜刺里跳将出来横刀立马就问你要答案的人。展示你的失败,又是一种唤起我强烈的同情心的有效工具。至此,就算我真的很忙,我也会主动凑上来看看能否帮忙。

  3. 他的问题排版很整齐,段落分明。于是我投降了,开始动手在纸上画立方体,准备解决问题。

后来我叫他把问题和答案发论坛上,不要藏在微信群这种小众圈里,他也听从了我的建议。这是这一天我第一次破例在微信里说话。

还没完。过了几个小时,另一位杨荟大侠跳将出来,给了一个精炼得多的答案,我下巴都惊掉了,因为我窃以为自己用了十几年的 R,在下标取子集这种初级问题上应该早早过关了,然而并没有。我不知道 x[i] 这种取子集的方式还有一种特殊用法,并且这也解开了我若干年的疑惑:给一串行列坐标,如何从矩阵中提取那些坐标对应的元素?给定向量形式的 ij 之后,x[i, j] 会返回一个矩阵的子集,这个子集是由 ij 交叉得来的。比如下面的矩阵我想取第 1 行第 2 列的元素,以及第 3 行第 3 列的元素,那么第一种办法就是错的(因为行列下标交叉出了一个子矩阵),第二种办法才是对的,取出来的是两个元素:

(m = matrix(1:12, 3))
#      [,1] [,2] [,3] [,4]
# [1,]    1    4    7   10
# [2,]    2    5    8   11
# [3,]    3    6    9   12

m[c(1, 3), c(2, 3)]
#      [,1] [,2]
# [1,]    4    7
# [2,]    6    9

m[rbind(c(1, 2), c(3, 3))]
# [1] 4 9

第二种办法的下标是一个矩阵,而且方括号里只有一个参数(矩阵),没有第二个参数。这便是根据行列坐标分别取特定矩阵元素的办法。我太后知后觉了。

上一次我在微信群里破例发言是一个多月前因为杨洵默的关系。在我见过的人中,厉害的人不少,但这位默兄可算是我认为稀有的“脑力深邃”的人之一。我说的厉害的人,主要是在某一个或两个领域拔尖的人;而脑力深邃,则体现在知识领域跨度大到让人叹为观止。另外两个例子是左辰和 David Donoho。那感觉就是你站他们面前,会觉得眼前是一片浩瀚宇宙。


  1. 注意,通常情况下我并不鼓励用图片的方式发布关于代码的内容,因为这样让人很难直接运行你的代码。在微信群的特定条件下,为了不扰民,我觉得他的做法是值得称道的。