r - 如何按多列合并行,获取多列中的最后一个非空值?
问题描述
我正在学习如何使用 R 进行聚合操作,但是我经常使用一种特定类型的操作,我希望在 R 或其附加组件中有一个内置操作,或者至少有一个更好的操作实施比我想出的。我不确定这是否有技术术语,但我称之为 MUSH 操作。在这里,您基本上将一个脏数据集与一堆随机位置的缺失数据混合成一个干净的数据集。有时我需要第一个非空值,有时是最后一个,有时是最后一个值,无论它是否为空。为了简单起见,这里有一个例子,我只担心最后一个非空值。
假设我有一份学生名单,上面有他们的考试成绩、科目和进行考试的老师。数据输入人员有点粗心(纯属假设),并且遗漏了一些老师的名字。此外,还有一些学生在最初进行考试时缺席,不得不在以后参加考试。
这是一个示例数据集:
STUDENTID SUBJECT TEACHER SCORE
1: 100 Art <NA> 96
2: 100 Art Smith NA
3: 100 Science Jones 75
4: 101 Art Smith NA
5: 101 Art Smith 50
6: 101 Science Jones 75
7: 102 Art <NA> 80
8: 102 Art Smith NA
这是设置数据框的代码:
# Setup data
a<-data.table(cbind(
"STUDENTID"=c("100","100","101","102")
,"SUBJECT"=c("Art","Science","Art","Art"))
,"TEACHER"=c("Smith","Jones","Smith","Smith")
,"SCORE"=c(NA,75,50,NA)
)
b<-data.table(
"STUDENTID"=c("100","101","101","102")
,"SUBJECT"=c("Art","Art","Science","Art")
,"TEACHER"=c(NA,"Smith","Jones",NA)
,"SCORE"=c(96,NA,75,80)
)
# Merge data
d <- merge(a, b, by = NULL, all = TRUE)
# Show output
d
我想通过合并基于 STUDENTID 和 SUBJECT 的所有行来清理这个数据集。我想为其他每一行取第一个非空值。结果输出应如下所示:
STUDENTID SUBJECT TEACHER SCORE
1: 100 Art Smith 96
2: 100 Science Jones 75
3: 101 Art Smith 50
4: 101 Science Jones 75
5: 102 Art Smith 80
下面的代码完成了这个任务:
# dplyr to get last non null values
library(dplyr)
d <- d %>%
group_by(STUDENTID, SUBJECT) %>%
mutate(
bestTeacherRow = dplyr::last(na.omit(TEACHER)),
bestScoreRow = dplyr::last(na.omit(SCORE))
)
# Replace values with non-nulls
d$TEACHER <- d$bestTeacherRow
d$SCORE <- d$bestScoreRow
# Remove duplicates
d <- unique(d)
#Show output
d
有没有更优雅的方法来做到这一点?它是否使用 dplyr 或其他附加组件都没有关系。
更重要的是,有没有办法在不指定每个标头/变量名称的情况下做到这一点?例如,如果在将来某个时间点将执行测试的 DATE 添加到数据集中,我可以运行相同的代码并获得相同的结果。我经常不得不从我的数据集中添加或删除变量,并且不得不返回并在整个数据转换过程中手动更改它们变得非常快变得难以管理。
解决方案
另一个data.table
简单地找到第一个非NA
(如果存在)的选项:
d[, lapply(.SD, function(z) z[!is.na(z)][1]), by = .(STUDENTID, SUBJECT)]
# STUDENTID SUBJECT TEACHER SCORE
# <char> <char> <char> <num>
# 1: 100 Art Smith 96
# 2: 100 Science Jones 75
# 3: 101 Art Smith 50
# 4: 101 Science Jones 75
# 5: 102 Art Smith 80
推荐阅读
- excel - 主子调用多个同一个UD函数
- c++ - 有时只会出现 jni segv_accer 或 segv_mapper 错误
- scripting - 使用 WINDBg 脚本解析 Windows 转储文件
- javascript - 在 JavaScript 中使用 pipe() 和 compose() 函数?
- javascript - laravel 日期选择器的默认日期
- javascript - 如何强制在 Tumblr 主题的同一选项卡上打开外部链接?
- c++ - Dave Abrahams 和 Chris Diggins 的 C++ 接口思想有哪些现代替代方案
- amazon-cloudfront - PCI HTTP 标头安全要求和 AWS CloudFront
- reactjs - 使用底部导航操作更改屏幕时如何消除延迟?
- python - 无法弄清楚为什么图表没有更新