We can use summarise_all (assuming that there are only one non-NA element per 'Date' for each column)
library(dplyr)
df %>%
group_by(Date) %>%
summarise_all(na.omit)
If we have more than one non-NA element and also have some cases with only NAs, either create a list column or paste
df %>%
group_by(Date) %>%
summarise_at(vars(-group_cols()), ~ list(if(all(is.na(.))) .[n() + 1] else .[!is.na(.)]))
# A tibble: 3 x 4
# Date AAPL MSFT NASDAQ
# <chr> <list> <list> <list>
#1 1.1.19 <chr [1]> <chr [1]> <chr [1]>
#2 2.1.19 <chr [1]> <chr [1]> <chr [2]>
#3 3.1.19 <chr [1]> <chr [1]> <chr [2]>
Also, if some elements are repeated,then we take the unique and assuming that there are no completely distinct elements per group
df %>%
group_by(Date) %>%
summarise_at(vars(-group_cols()), ~ if(all(is.na(.))) .[n() + 1] else unique(.[!is.na(.)]))
# A tibble: 3 x 4
# Date AAPL MSFT NASDAQ
# <chr> <chr> <chr> <chr>
#1 1.1.19 <NA> <NA> <NA>
#2 2.1.19 2% 4% 5%
#3 3.1.19 3% 5% 6%
Or do the distinct first and then do a group by operation
distinct(df) %>%
group_by(Date) %>%
summarise_at(vars(-group_cols()), ~ .[!is.na(.)][1])
# A tibble: 3 x 4
# Date AAPL MSFT NASDAQ
# <chr> <chr> <chr> <chr>
#1 1.1.19 <NA> <NA> <NA>
#2 2.1.19 2% 4% 5%
#3 3.1.19 3% 5% 6%
Or in the devel version of dplyr, we can use condense
df %>%
group_by(Date) %>%
condense(data = across(everything(), ~ .[!is.na(.)]))
# A tibble: 3 x 2
# Rowwise: Date
# Date data
# <chr> <list>
#1 1.1.19 <tibble [0 × 3]>
#2 2.1.19 <tibble [2 × 3]>
#3 3.1.19 <tibble [2 × 3]>
data
df <- structure(list(Date = c("1.1.19", "2.1.19", "3.1.19", "1.1.19",
"2.1.19", "3.1.19"), AAPL = c(NA, "2%", "3%", NA, NA, NA), MSFT = c(NA,
NA, NA, NA, "4%", "5%"), NASDAQ = c(NA, "5%", "6%", NA, "5%",
"6%")), class = "data.frame", row.names = c(NA, -6L))