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