У меня есть этот набор данных со значениями для близнецов в семьях:
zyg fid x_t1 x_t2 y_t1 y_t2
1 499474 NA 1 1 NA
1 499474 NA NA NA NA
1 499474 NA NA NA 1
1 499474 NA NA NA NA
1 499540 NA NA 1 NA
1 499540 NA NA NA NA
2 499874 NA NA NA NA
2 499874 NA NA 1 NA
2 499874 NA NA NA 1
2 499874 2 NA NA 1
Ожидается для семейства 499479:
zyg fid x_t1 x_t2 y_t1 y_t2
1 499474 NA 1 1 1
а для семейства 499874 должно быть:
2 499874 2 NA 1 1





Вы можете использовать следующий код:
library(dplyr)
df %>%
group_by(fid) %>%
summarise_all(~first(na.omit(.)))
Выход:
# A tibble: 3 × 6
fid zyg x_t1 x_t2 y_t1 y_t2
<int> <int> <int> <int> <int> <int>
1 499474 1 NA 1 1 1
2 499540 1 NA NA 1 NA
3 499874 2 2 NA 1 1
Ваши данные:
df<-structure(list(zyg = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L
), fid = c(499474L, 499474L, 499474L, 499474L, 499540L, 499540L,
499874L, 499874L, 499874L, 499874L), x_t1 = c(NA, NA, NA, NA,
NA, NA, NA, NA, NA, 2L), x_t2 = c(1L, NA, NA, NA, NA, NA, NA,
NA, NA, NA), y_t1 = c(1L, NA, NA, NA, 1L, NA, NA, 1L, NA, NA),
y_t2 = c(NA, NA, 1L, NA, NA, NA, NA, NA, 1L, 1L)), class = "data.frame", row.names = c(NA,
-10L))
Если в группе есть только один элемент, не относящийся к NA
library(dplyr)
df1 %>%
group_by(zyg, fid) %>%
summarise(across(everything(), ~ .x[complete.cases(.x)][1]), .groups = "drop")
-выход
# A tibble: 3 × 6
zyg fid x_t1 x_t2 y_t1 y_t2
<int> <int> <int> <int> <int> <int>
1 1 499474 NA 1 1 1
2 1 499540 NA NA 1 NA
3 2 499874 2 NA 1 1
df1 <- structure(list(zyg = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L
), fid = c(499474L, 499474L, 499474L, 499474L, 499540L, 499540L,
499874L, 499874L, 499874L, 499874L), x_t1 = c(NA, NA, NA, NA,
NA, NA, NA, NA, NA, 2L), x_t2 = c(1L, NA, NA, NA, NA, NA, NA,
NA, NA, NA), y_t1 = c(1L, NA, NA, NA, 1L, NA, NA, 1L, NA, NA),
y_t2 = c(NA, NA, 1L, NA, NA, NA, NA, NA, 1L, 1L)),
class = "data.frame", row.names = c(NA,
-10L))
Другое возможное решение:
library(dplyr)
df %>%
group_by(zyg, fid) %>%
summarise(across(everything(), ~ if (all(is.na(.x))) {NA} else
{max(.x, na.rm = T)}), .groups = "drop")
#> # A tibble: 3 × 6
#> zyg fid x_t1 x_t2 y_t1 y_t2
#> <int> <int> <int> <int> <int> <int>
#> 1 1 499474 NA 1 1 1
#> 2 1 499540 NA NA 1 NA
#> 3 2 499874 2 NA 1 1
очень похоже на другие ответы, но я также хотел дать свое собственное решение.
df %>%
group_by(zyg,fid) %>%
summarise(across(everything(),~sum(.,na.rm=TRUE))
)
Вы хотите сделать что-то, что coalesce делает по строкам для столбцов:
Вот как вы можете это сделать:
libarary(dplyr)
coalesce_by_column <- function(df) {
return(dplyr::coalesce(!!! as.list(df)))
}
df %>%
group_by(fid) %>%
summarise(across(everything(), coalesce_by_column))
fid zyg x_t1 x_t2 y_t1 y_t2
<int> <int> <int> <int> <int> <int>
1 499474 1 NA 1 1 1
2 499540 1 NA NA 1 NA
3 499874 2 2 NA 1 1
Вот еще один возможный вариант с использованием fill и slice:
library(tidyverse)
df %>%
group_by(zyg, fid) %>%
fill(everything(), .direction = "downup") %>%
slice(1)
Выход
zyg fid x_t1 x_t2 y_t1 y_t2
<int> <int> <int> <int> <int> <int>
1 1 499474 NA 1 1 1
2 1 499540 NA NA 1 NA
3 2 499874 2 NA 1 1
Данные
df <- structure(list(zyg = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L
), fid = c(499474L, 499474L, 499474L, 499474L, 499540L, 499540L,
499874L, 499874L, 499874L, 499874L), x_t1 = c(NA, NA, NA, NA,
NA, NA, NA, NA, NA, 2L), x_t2 = c(1L, NA, NA, NA, NA, NA, NA,
NA, NA, NA), y_t1 = c(1L, NA, NA, NA, 1L, NA, NA, 1L, NA, NA),
y_t2 = c(NA, NA, 1L, NA, NA, NA, NA, NA, 1L, 1L)), class = "data.frame", row.names = c(NA,
-10L))