写
在前面
Hello亲爱的小伙伴们,大猫课堂又回来啦。从今天开始大猫会选择一些Stackoverflow.com上有关R数据处理的问答摘录给大家。这些问题都是在平日的工作中有很高可能性出现并且看似容易实则让人抓狂的问题,在Stackoverflow上他们有着很高的人气。事实上,这些问题也就是你在“看懂一本R的教材”和“成为R大神”之间的距离。大猫除了进行翻译,也会在其中增加一些相关知识点,相信掌握了这些问题,一定会对你的研究工作大有裨益。
1. 这些问题大多数涉及到用data.table包处理数据。data.table是目前R中人气最高的数据处理包。
2. 如果要自己寻找Stackoverflow上与R或是data.table相关的问题,可以在搜索栏输入[R] [data.table] Your question。
提
出问题
好啦,开始上课!
首先,假设我有一个这样的数据集(暂且命名为t1):
现在我想做的是对于每一行,找出非NA的值,填充到“mean.scale”这个新的变量;如果有多个非NA,那么就计算其平均值。也就是说,我希望最终得到如下数据集:
原问题大家可以访问以下链接:http://stackoverflow.com/questions/23521323/r-data-table-for-computing-summary-stats-across-multiple-columns
解
题思路
在解决本问题的过程中我们需要用到data.table包!
”
Stackoverflow上有人提出了这个问题,大神eddi提出了解决方案:
"It'll be easiest to rearrange you data a little..."
解
题步骤
如何rearrange呢?eddi大神的意思是,原来inti_total_asset和issuing_scale是两个变量,现在要把他们stack起来,“堆成”一列,也就是这样:
相应的代码是(t1是原始数据集):
▶ t2 <- t1[, list(mean.scale = c(init_total_asset, issuing_scale)), by = .(fund_name)]
其中的关键在于拼接函数c(),它将不同列的向量拼接成了一列。另外,这个操作是不是有点熟悉?对,这个步骤和cast和melt函数的作用类似,只不过这里直接用了data.table自己的语句。事实上,data.table也整合了reshape中的cast和melt函数,并且将cast函数升级为dcast,感兴趣的小伙伴可以去研究一番。
在拉直数据后,接下来要做的工作就很简单了。我们只要把数据按照fund_name分组,然后对每组求scale的均值。唯一需要注意的有两点。首先,别忘了mean中的na.rm = T参数,它能够让函数忽略缺失值。其次,最后计算出的结果中会有NaN(not a number)值,产生这种情况是因为在计算均值中出现了0作为除数的情况,对此我们需要用!is.finite()将其排除。代码如下:
▶ t3 <- t2[, .(mean.scale = mean(mean.scale, na.rm = T)), by = fund_name][is.finite(mean.scale)][is.finite(mean.scale)]
结果是这个样子的:
看,胜利就在前方,最后,我们只要把mean.scale合并到原来的数据集就行,代码如下(t1是原始数据集):
▶ t4 <- t3[t1, on = "fund_name", nomatch = 0]
结果如下:
事实上,大猫把整个过程分解成了好几步,如果对于data.table包比较熟悉,完全可以在一行之内搞定所有事情,根本不需要把进行数据集的拆分、合并:
▶ t.final <- t1[, ":="(mean.scale = mean(c(init_total_asset, issuing_scale), na.rm = T)), by = .(fund_name)][is.finite(mean.scale)]
提示:把所有步骤打包成一步的关键在于“:=”符号的运用。
本
期总结
本期大猫带领大家学习了如何在R中按照行进行处理。R的数据处理哲学是向量,是列,但这并不妨碍我们按照行进行处理,其中的关键,就在于运用 c() 函数把不同的向量拼接成一个向量。
我是大猫,咱们下期见!
附:Stackoverflow的原始问题