R 如何在删除NA值时将多个记录合并为一个记录
假设我有以下数据帧R 如何在删除NA值时将多个记录合并为一个记录,r,coalesce,R,Coalesce,假设我有以下数据帧df name <- c("Bill", "Rob", "Joe", "Joe") address <- c("123 Main St", "234 Broad St", NA, "456 North Ave") favteam <- c("Dodgers", "Mets", "Pirates", NA) df <- data.frame(name = name, address = address,
df
name <- c("Bill", "Rob", "Joe", "Joe")
address <- c("123 Main St", "234 Broad St", NA, "456 North Ave")
favteam <- c("Dodgers", "Mets", "Pirates", NA)
df <- data.frame(name = name,
address = address,
favteam = favteam)
df
以下是dplyr的一个选项:
library(dplyr)
df %>%
group_by(name) %>%
summarise_each(funs(first(.[!is.na(.)]))) # or summarise_each(funs(first(na.omit(.))))
#Source: local data frame [3 x 3]
#
# name address favteam
#1 Bill 123 Main St Dodgers
#2 Joe 456 North Ave Pirates
#3 Rob 234 Broad St Mets
并使用data.table:
library(data.table)
setDT(df)[, lapply(.SD, function(x) x[!is.na(x)][1L]), by = name]
# name address favteam
#1: Bill 123 Main St Dodgers
#2: Rob 234 Broad St Mets
#3: Joe 456 North Ave Pirates
或
编辑: 你说在你的实际数据中,每个名字有不同数量的非NA响应。在这种情况下,以下方法可能会有所帮助 考虑修改后的示例数据(查看最后一行):
Joe能否改变他对团队的看法,或者在第二条记录或后续记录上更正他的地址?Joe生活在网格之外,积极避免数据收集器。我们只找到了他两次,他强烈反对告诉我们关于他的生活的任何事情,但幸运的是,他喜欢谈论棒球,所以……撇开玩笑不谈,不同的非NA反应又给我的问题增添了一道皱纹,但我想我会一步一步地去做。关于实现基于因子变量中级别顺序的层次结构,您有什么想法吗?这类问题似乎没有得到回答,所以……你所说的“基于因子变量中的级别顺序实现层次结构”是什么意思?你能解释得更详细一点吗?如果每个名字都有不同的非NA回答,你会有什么期待?回答得很好——谢谢你对细节的关注,@docendo。我特别喜欢
dplyr
解决方案,因为我的清单上列出了该解决方案,以便更熟悉该包的语法。对于这一部分:summary_each(funs(first(.[!is.na(.))))
,句号是指按name
分组的df
的简写方式吗?我不知道dplyr在索引方面玩得很好。另外,如果您能向我推荐一本关于dplyr
@mcjudd的详细教程,我将不胜感激,很高兴它起到了作用:)在摘要中的
每个
都是指a)分组和b)列的当前数据。所以first(.[!is.na(.)])
的意思是:在我们总结的每一列和该列中的每组name
中,取第一个不是na
的数据点,并将其作为该列中该组的总结值返回。不幸的是,我不能告诉你很多关于dplyr的教程。例如,如果你只是用谷歌搜索它,你会发现很多。@mcjudd,我不确定我是否完全理解你的意思,但你可以尝试用…%>%扩展dplyr管道mutate_each(funs(replace(,which(==0),1))
。您也可以使用ifelse,但replace速度更快。从技术上讲,您也可以在摘要each中执行此操作,但这会降低其可读性,更重要的是,您不需要按组执行此操作(在总结之后,数据不再分组,因此以后每个数据都进行变异会更好)。抱歉,愚蠢的问题。解决了。总结每个数据(funs(first(.[!is.na(.)),max))
:)@mcjudd,另请参阅相关问题
library(dplyr)
df %>%
group_by(name) %>%
summarise_each(funs(first(.[!is.na(.)]))) # or summarise_each(funs(first(na.omit(.))))
#Source: local data frame [3 x 3]
#
# name address favteam
#1 Bill 123 Main St Dodgers
#2 Joe 456 North Ave Pirates
#3 Rob 234 Broad St Mets
library(data.table)
setDT(df)[, lapply(.SD, function(x) x[!is.na(x)][1L]), by = name]
# name address favteam
#1: Bill 123 Main St Dodgers
#2: Rob 234 Broad St Mets
#3: Joe 456 North Ave Pirates
setDT(df)[, lapply(.SD, function(x) head(na.omit(x), 1L)), by = name]
name <- c("Bill", "Rob", "Joe", "Joe", "Joe")
address <- c("123 Main St", "234 Broad St", NA, "456 North Ave", "123 Boulevard")
favteam <- c("Dodgers", "Mets", "Pirates", NA, NA)
df <- data.frame(name = name,
address = address,
favteam = favteam)
df
# name address favteam
#1 Bill 123 Main St Dodgers
#2 Rob 234 Broad St Mets
#3 Joe <NA> Pirates
#4 Joe 456 North Ave <NA>
#5 Joe 123 Boulevard <NA>
setDT(df)[, lapply(.SD, function(x) unique(na.omit(x))), by = name]
# name address favteam
#1: Bill 123 Main St Dodgers
#2: Rob 234 Broad St Mets
#3: Joe 456 North Ave Pirates
#4: Joe 123 Boulevard Pirates