Jak mogę skondensować to Dataframe:

Date    AAPL   MSFT NASDAQ
1.1.19  NA     NA   NA
2.1.19  2%     NA   5%
3.1.19  3%     NA   6%
...
1.1.19  NA     NA   NA
2.1.19  NA     4%   5%
3.1.19  NA     5%   6%
...

Wygladać jak:

Date    AAPL   MSFT NASDAQ
1.1.19  NA     NA   NA
2.1.19  2%     4%   5%
3.1.19  3%     5%   6%
...

Czy istnieje funkcja, aby nie mieć duplikatów dat i wartości NASDAQ, usuwa NA s?

Dzięki!

2
Ben 8 marzec 2020, 20:45

1 odpowiedź

Najlepsza odpowiedź

Możemy użyć summarise_all (zakładając, że istnieją tylko jeden element non-na "daty" dla każdej kolumny)

library(dplyr)
df %>%
   group_by(Date) %>%
   summarise_all(na.omit)

Jeśli mamy więcej niż jeden element non-na, a także mieć kilka przypadków tylko NAS, utworzyć kolumnę list lub 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]>

Ponadto, jeśli niektóre elementy są powtarzane, bierzemy unique i zakładamy, że nie ma zupełnie odrębnych elementów na grupę

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%  

Lub wykonaj distinct, a następnie wykonaj grupę według działania

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%   

Lub w wersji devel dplyr możemy użyć 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]>

Dane

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))
2
akrun 8 marzec 2020, 22:26