Мы можем использовать summarise_all
(при условии, что для каждого столбца имеется только один элемент, отличный от NA, для каждой даты)
library(dplyr)
df %>%
group_by(Date) %>%
summarise_all(na.omit)
Если у нас более одного элемента, отличного от NA а также в некоторых случаях только с NA, либо создайте столбец list
, либо 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]>
Кроме того, если некоторые элементы повторяются, мы берем unique
и предполагаем, что нет Совершенно отдельные элементы для каждой группы
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%
Или сначала выполните distinct
, а затем выполните группу по операции
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%
Или в devel
версии dplyr
мы можем использовать 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))