Могу ли я определить по строке первое и последнее наблюдение - PullRequest
2 голосов
/ 26 июня 2019

хотел бы определить количество фирм, которые начинаются и заканчиваются каждый месяц. Цель состоит в том, чтобы по столбцу сказать, сколько фирм начинаются и заканчиваются.

Мои данные выглядят так, с большим количеством строк и столбцов.

  Firm   Return_1990_01  Return_1990_02 Return_1990_03 Return_1990_04 Return_1990_05 
#1 fg23         NaN             NaN             1.54          2.34        .641      
#2 sdf1         1.35            NaN             3.53          NaN         .231     
#3 sdf1         1.12            2.44            1.51          1.64         NaN     

Одна проблема состоит в том, что фирма может иметь NaN между ними. Например, во 2-й строке фирма начинает 1990_01 и заканчивается 1990_05, несмотря на то, что NaN между ними.

Я попробовал следующий код

library(dplyr)
library(tidyr)

df %>% 
  gather(month, value, -Firm) %>% 
  filter(!is.nan(value)) %>% 
  arrange(Firm, month) %>% 
  group_by(Firm) %>% 
  summarise(start = first(month), end = last(month))

Но получите следующее сообщение об ошибке

Error in arrange_impl(.data, dots) : 
  data frame column with incompatible number of rows (465), expecting : 59378

Любая помощь приветствуется.

Ответы [ 3 ]

2 голосов
/ 26 июня 2019

Вы можете сделать

apply(df[,-1], 1, function(x) range(which(!is.nan(x))))
#      [,1] [,2] [,3]
# [1,]    3    1    1
# [2,]    5    5    4

Если вы хотите добавить имена к строкам и столбцам, мы можем расширить это как:

apply(df[,-1], 1, function(x) range(which(!is.nan(x)))) %>%
  t %>%
  `colnames<-`(c('First','Last')) %>%
  `row.names<-`(df[,1])
#      First Last
# fg23     3    5
# sdf1     1    5
# sdf1     1    4
1 голос
/ 26 июня 2019

Другой способ представить это с именами столбцов, используя tidyverse.Мы gather данных в длинном формате и выбираем только первое и последнее значение для каждой строки.Создайте новый столбец (temp), который содержит "Start" и "End" для каждой группы и spread для широкого формата.

library(dplyr)
library(tidyr)

df %>%
  mutate(row = row_number()) %>%
  gather(key, value, -Firm, -row, na.rm = TRUE) %>%
  group_by(row) %>%
  slice(c(1L, n())) %>%
  mutate(temp = c("Start", "End")) %>%
  select(-value) %>%
  spread(temp, key) %>%
  ungroup %>%
  select(-row) %>%
  select(Firm, Start, End)

#  Firm  Start          End           
#  <fct> <chr>          <chr>         
#1 fg23  Return_1990_03 Return_1990_05
#2 sdf1  Return_1990_01 Return_1990_05
#3 sdf1  Return_1990_01 Return_1990_04
0 голосов
/ 26 июня 2019

С tidyverse мы можем сделать это без изменения формы с pmap. Найдите names элементов, которые не являются NaN с which, получите имена столбцов first и last

library(tidyverse)
df  %>% 
   transmute(Firm, start_end = pmap(.[-1], ~ 
       which(!is.nan(c(...))) %>%
       names %>%
       range %>%
       {tibble(start = first(.), end = last(.))})) %>%
   unnest
#  Firm          start            end
#1 fg23 Return_1990_03 Return_1990_05
#2 sdf1 Return_1990_01 Return_1990_05
#3 sdf1 Return_1990_01 Return_1990_04

В base R мы также можем сделать это векторизованным способом с max.col

m1 <- !is.na(df[-1])
start <- colnames(m1)[max.col(m1, "first")]
end <- colnames(m1)[max.col(m1, "last")]
cbind(df1['Firm'], start, end)
#  Firm          start            end
#1 fg23 Return_1990_03 Return_1990_05
#2 sdf1 Return_1990_01 Return_1990_05
#3 sdf1 Return_1990_01 Return_1990_04
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...