Конденсатор - PullRequest
       0

Конденсатор

1 голос
/ 08 марта 2020

Как мне сжать этот :

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%
...

, чтобы он выглядел следующим образом:

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

Есть ли функция, чтобы не иметь повторяющихся дат и значений NASDAQ , удаляет NA s?

Спасибо!

Ответы [ 2 ]

1 голос
/ 08 марта 2020

Мы можем использовать 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))
0 голосов
/ 09 марта 2020

Вот некоторые базовые решения R:

  • Использование split + rbind
dfout <- do.call(rbind,
                 c(make.row.names = F,
                   Map(function(z) data.frame(Map(function(x) ifelse(all(is.na(x)),NA,na.omit(x)),z)),
                       split(df,df$Date))))
  • Использование ave + unique
dfout <- unique(cbind(df[1],
                      sapply(df[-1],
                             function(q) ave(q,df$Date,FUN = function(x) ifelse(all(is.na(x)),NA,na.omit(x))))))

такой, что

> dfout
    Date AAPL MSFT NASDAQ
1 1.1.19 <NA> <NA>   <NA>
2 2.1.19   2%   4%     5%
3 3.1.19   3%   5%     6%

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))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...