如何在 R 中合并同一数据框中的行

How do I merge rows in the same dataframe in R

我有一个大型数据集,如下所示:

   data.frame(cbind(id=c(01,01,02,03,04,04),sex=c("---","m","f","m","---","f"),
             age=c(20,NA,25,23,NA,18),height=c(NA,180,175,168,176,NA),
             weight=c(68,NA,65,68,NA,NA)))

     id sex  age height weight
     01 ---   20   <NA>     68
     01   m <NA>    180   <NA>
     02   f   25    175     65
     03   m   23    168     68
     04 --- <NA>    176   <NA>
     04   f   18   <NA>   <NA>

如何合并行以像这样填写缺失值:

     id sex  age height weight
     01  m   20   180     68
     02  f   25   175     65
     03  m   23   168     68
     04  f   18   176   <NA>
     

感谢您的帮助。

我们可以按 'id'、summarise across 等列进行分组,将 --- 转换为 NA,同时删除 NA na.omit 的元素(我们假设所有列都具有相同数量的 NA 元素)。如果一个组的所有元素都是 NA,return NA

library(dplyr)    
df1 %>% 
  group_by(id) %>% 
  summarise(across(everything(), 
      ~ if(all(is.na(.))) NA else na.omit(na_if(., '---'))), .groups = 'drop')

-输出

# A tibble: 4 x 5
#     id sex     age height weight
#* <dbl> <chr> <dbl>  <dbl>  <dbl>
#1     1 m        20    180     68
#2     2 f        25    175     65
#3     3 m        23    168     68
#4     4 f        18    176     NA

我们还可以 order 基于 NA--- 的单独列,在按 'id' 分组后,然后使用 filterif_all 删除那些只有缺失元素的行

df1 %>% 
  group_by(id) %>% 
  mutate(across(everything(), ~ .[order(is.na(.)| . == '---')])) %>% 
  filter(!if_all(everything(),  ~ is.na(.)|. == '---')) %>% 
  ungroup
# A tibble: 4 x 5
#     id sex     age height weight  
#   <dbl> <chr> <dbl>  <dbl>  <dbl>
#1     1 m        20    180     68
#2     2 f        25    175     65
#3     3 m        23    168     68
#4     4 f        18    176     NA

数据

df1 <- structure(list(id = c(1, 1, 2, 3, 4, 4), sex = c("---", "m", 
"f", "m", "---", "f"), age = c(20, NA, 25, 23, NA, 18), height = c(NA, 
180, 175, 168, 176, NA), weight = c(68, NA, 65, 68, NA, NA)), 
class = "data.frame", row.names = c(NA, 
-6L))
library(dplyr)
library(tidyr)

df %>% 
  group_by(id) %>% 
  fill(everything()) %>% 
  filter(sex != "---") %>%
  ungroup()

fill 的默认方向是“向下”,因此在给定数据帧的顺序的情况下这会起作用。否则,您必须先安排您的数据框。

输出

  id    sex   age   height weight
  <chr> <chr> <chr> <chr>  <chr> 
1 1     m     20    180    68    
2 2     f     25    175    65    
3 3     m     23    168    68    
4 4     f     18    176    NA 

data.table 解决方案是这样的

假设您的 data.frame 被命名为 DT

library(data.table)
setDT(DT) #convert the dataframe to data.table
DT[,lapply(.SD, max,na.rm=TRUE),by='id']

data.table 的语法是 DT[i, j, by],其中 i 是过滤器,j 是动作,by 是分组。我们在这里做的是,首先以逗号开头,因为我们没有进行任何过滤,所以我们的 i 在这种情况下是空白的。我们的 jlapply(.SD,max,na.rm=TRUE)lapply 只是一个循环,returns 一个列表,它在 .SD 上循环,这是一个 data.table 函数,基本上意味着所有列。 lapply 的第二个参数是我们要对所有列执行的函数。第三个参数是一个额外的参数,它被馈送到 max 以便它会忽略 NAs。 by 参数是您的 'id',这是您希望行唯一的依据。

这个答案的警告是,如果你有多个正确的值,那么这会取其中最大的一个,所以你需要用更合适的东西替换 max