假设我有以下data.frame df
患者家乡和一个任意临床指标,心率:
id <- c(rep(1:3, each = 2), rep(4, 3))
pt_hometown <- c("Atlanta", NA,
NA, "San Diego",
NA, NA,
"San Francisco", "Seattle", NA)
pt_heartrate <- c(NA, 82,
NA, NA,
76, 76,
90, 93, NA)
df <- data.frame(id = id,
pt_hometown = pt_hometown,
pt_heartrate = pt_heartrate,
stringsAsFactors = FALSE)
df
哪个给出了
id pt_hometown pt_heartrate
1 Atlanta NA
1 <NA> 82
2 <NA> NA
2 San Diego NA
3 <NA> 76
3 <NA> 76
4 San Francisco 90
4 Seattle 93
4 <NA> NA
As I've learned here,summarise_each
可以将一个或多个函数应用于分组数据框,以将记录折叠为每个组一个。最简单的情况可能是从df
中的所有变量中选择第一个非NA值,然后将它们折叠为每个组中的一个。
df1 <- df %>%
group_by(id) %>%
summarise_each(funs(first(.[!is.na(.)]))
df1
id pt_hometown pt_heartrate
1 Atlanta 82
2 San Diego NA
3 NA 76
4 San Francisco 90
当然,对于实际应用,人们可能希望以更具体的特性崩溃。我知道如何按类型对df
个变量进行分组,例如,选择每max
的{{1}}心率并折叠为一条记录,但我不知道的内容该怎么做是有条件地将字符变量折叠为每组一个记录,因为只有一个唯一的非NA值。
更具体地说,考虑id
编号为4的患者。他们有id
,“旧金山”和“西雅图”两个独特的值。显然两者都不正确。所以我想折叠每个只有一个非NA值的组的记录,但保留存在多个非NA元素的行,然后引起我们小组的注意,以决定如何纠正原始数据集中的错误。
所以我希望pt_hometown
看起来像这样:
df1
这是我尝试过的:
id pt_hometown pt_heartrate
1 Atlanta 82
2 San Diego NA
3 <NA> 76
4 San Francisco 90
4 Seattle 93
答案 0 :(得分:4)
我对某些边缘情况你想要什么有点不清楚,但这适用于OP:
library(data.table)
dt = as.data.table(df) # or convert in place using setDT
unique(dt, by = c('id', 'pt_hometown'))[, lapply(.SD, na.omit), by = id]
# id pt_hometown pt_heartrate
#1: 1 Atlanta 82
#2: 2 San Diego NA
#3: 3 NA 76
#4: 4 San Francisco 90
#5: 4 Seattle 93
答案 1 :(得分:3)
如上所述,目前无法使用具有可变行数的dplyr::summarise_each
来返回。
如果您想继续使用dplyr,可以使用mutate_each
和distinct
来解决这个问题。
以下是一个例子:
f <- function(.) if(length(unique(.[!is.na(.)])) > 1L) . else first(.[!is.na(.)])
df %>%
group_by(id) %>%
mutate_each(funs(f)) %>%
ungroup() %>%
distinct() %>%
filter(rowSums(is.na(.)) < 2L) # assuming you don't have NAs in the ID column
#Source: local data frame [5 x 3]
#
# id pt_hometown pt_heartrate
#1 1 Atlanta 82
#2 2 San Diego NA
#3 3 NA 76
#4 4 San Francisco 90
#5 4 Seattle 93
但是,我在回答您之前的问题或者eddi的问题时采用的data.table方法可能更有效。