合并数据框中的行,其中行不相交并包含 NA

Posted

技术标签:

【中文标题】合并数据框中的行,其中行不相交并包含 NA【英文标题】:Merge rows in a dataframe where the rows are disjoint and contain NAs 【发布时间】:2012-12-25 11:35:59 【问题描述】:

我有一个包含两行的数据框:

| code | name  | v1 | v2 | v3 | v4 |
|------|-------|----|----|----|----|
| 345  | Yemen | NA | 2  | 3  | NA |
| 346  | Yemen | 4  | NA | NA | 5  |

有没有一种简单的方法可以合并这两行? 如果我将“345”重命名为“346”,会不会更容易?

【问题讨论】:

您需要一些规则来组合非 NA 列。比如你总是取第一次出现还是最后一次出现,数字列的平均值等。 这里需要 coalesce() 功能。在这个线程上找到了一个很好的讨论:[link]***.com/questions/19253820/… 【参考方案1】:

您可以使用aggregate。假设您要合并列name 中具有相同值的行:

aggregate(x=DF[c("v1","v2","v3","v4")], by=list(name=DF$name), min, na.rm = TRUE)
   name v1 v2 v3 v4
1 Yemen  4  2  3  5

这就像 SQL SELECT name, min(v1) GROUP BY namemin函数是任意的,你也可以使用maxmean,它们都从NA返回非NA值,如果na.rm = TRUE返回非NA值。 (如果存在于 R 中,类似 SQL 的 coalesce() 函数听起来会更好。)

但是,您应该首先检查给定 name 的所有非 NA 值是否相同。例如,将aggregateminmax 一起运行并进行比较,或者与range 一起运行。

最后,如果您有比 v1-4 更多的变量,您可以使用 DF[,!(names(DF) %in% c("code","name"))] 来定义列。

【讨论】:

运行你的例子给了我Error in DF$name : $ operator is invalid for atomic vectors @MattO'Brien 你的 DF 怎么样?是数据框吗?如果有多个列吗?你有复制错误的代码吗?【参考方案2】:

添加 dplyrdata.table 解决方案以确保完整性

使用dplyr::coalesce()

library(dplyr)

sum_NA <- function(x) if (all(is.na(x))) x[NA_integer_] else sum(x, na.rm = TRUE)

df %>% 
  group_by(name) %>% 
  summarise_all(sum_NA)
#> # A tibble: 1 x 6
#>   name   code    v1    v2    v3    v4
#>   <fct> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Yemen   691     4     2     3     5

# Ref: https://***.com/a/45515491
# Supply lists by splicing them into dots:
coalesce_by_column <- function(df) 
  return(dplyr::coalesce(!!! as.list(df)))


df %>% 
  group_by(name) %>% 
  summarise_all(coalesce_by_column)
#> # A tibble: 1 x 6
#>   name   code    v1    v2    v3    v4
#>   <fct> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Yemen   345     4     2     3     5

使用data.table

# Ref: https://***.com/q/28036294/
library(data.table)
setDT(df)[, lapply(.SD, na.omit), by = name]
#>     name code v1 v2 v3 v4
#> 1: Yemen  345  4  2  3  5
#> 2: Yemen  346  4  2  3  5

setDT(df)[, code := NULL][, lapply(.SD, na.omit), by = name]    
#>     name v1 v2 v3 v4
#> 1: Yemen  4  2  3  5

setDT(df)[, code := NULL][, lapply(.SD, sum_NA), by = name]
#>     name v1 v2 v3 v4
#> 1: Yemen  4  2  3  5

【讨论】:

以上是关于合并数据框中的行,其中行不相交并包含 NA的主要内容,如果未能解决你的问题,请参考以下文章

在数据框中查找包含NA的列的行?

组合 Geopandas 数据框中的行

基于正则表达式合并数据框中的变量对

合并数据框中的行[重复]

算法导论——用于不相交集合的数据结构

Javascript画布 - 矩形中的相交圆孔或如何合并多个圆弧路径