说我有以下数据框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
看起来像:
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>
我想要做的是按名称(或一般来说,任意数量的ID变量)进行折叠,并使用除NA
之外的任何其他值替换最终数据中的NA
值,像这样:
df_collapse <- foo(df)
name address favteam
1 Bill 123 Main St Dodgers
2 Rob 234 Broad St Mets
3 Joe 456 North Ave Pirates
答案 0 :(得分:12)
这是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
或
setDT(df)[, lapply(.SD, function(x) head(na.omit(x), 1L)), by = name]
编辑:
您说在实际数据中,每个名字都有不同数量的非NA回复。在这种情况下,以下方法可能会有所帮助。
考虑这个修改过的样本数据(查看最后一行):
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>
然后,您可以使用此data.table方法获取可能因名称而有所不同的非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