R,dplyr:如果每个组只有一个唯一的非NA元素,则按组折叠字符变量元素

时间:2015-02-23 19:08:38

标签: r dplyr

假设我有以下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 heresummarise_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

2 个答案:

答案 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_eachdistinct来解决这个问题。

以下是一个例子:

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方法可能更有效。