我有一个包含两行的数据框:
| code | name | v1 | v2 | v3 | v4 |
|------|-------|----|----|----|----|
| 345 | Yemen | NA | 2 | 3 | NA |
| 346 | Yemen | 4 | NA | NA | 5 |
有没有简单的方法可以合并这两行? 如果我将“345”重命名为“346”,会不会更容易一些?
我有一个包含两行的数据框:
| code | name | v1 | v2 | v3 | v4 |
|------|-------|----|----|----|----|
| 345 | Yemen | NA | 2 | 3 | NA |
| 346 | Yemen | 4 | NA | NA | 5 |
有没有简单的方法可以合并这两行? 如果我将“345”重命名为“346”,会不会更容易一些?
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 name
。 min
函数是任意的,你也可以使用max
或mean
,所有这些函数都将返回非NA值,如果na.rm = TRUE
,则从NA和非NA值中返回。
然而,你首先应该检查给定name
的所有非NA值是否相同。例如,分别使用min
和max
来运行aggregate
并进行比较,或者使用range
运行它。
最后,如果你有比v1-4更多的变量,你可以使用DF[,!(names(DF) %in% c("code","name"))]
来定义列。
DF$name: $ operator is invalid for atomic vectors
。 - tumultous_rooster为了让内容更加完整,我们将介绍使用 dplyr
和 data.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://dev59.com/M1cO5IYBdhLWcg3wny6-#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://dev59.com/JV4c5IYBdhLWcg3wVpFI/
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