报告变量

时间:2017-09-11 10:00:00

标签: r dplyr

我想知道我在may数据帧中的所有变量的第一个和最后一个非缺失的观察结果。

library(tidyverse)

df <- tribble(
  ~year, ~country, ~series1, ~series2, 
  #--|--|--|----
  2003, "USA", NA, 5,
  2004, "USA", NA, 6, 
  2005, "USA", NA, 7, 
  2006, "USA", 10, 8,
  2007, "USA", NA, 4,
  2008, "USA", NA, 10,
  2009, "USA", 16, 12,
  2010, "USA", 12, 8,
  2011, "USA", 12, 13,
  2012, "USA", 13, 10,
  2013, "USA", 11, 5,
  2005, "FRA", 5, NA, 
  2006, "FRA", 6, NA, 
  2007, "FRA", 5, NA, 
  2008, "FRA", 4, NA,
  2009, "FRA", 9, NA,
  2010, "FRA", 7, NA, 
  2011, "FRA", 14, NA,
  2012, "FRA", 7, 11, 
  2013, "FRA", 6, 6,
  2014, "FRA", 5, 7,
  2015, "FRA", 4, 5
)

df_stats <- df %>%
  group_by(country) %>%
  summarize(First = min(year, na.rm = TRUE),
            Last  = max(year, na.rm = TRUE))

返回df_stats

--------------------------
| country | First | Last |
--------------------------
| FRA     | 2005  | 2015 |
--------------------------
| USA     | 2003  | 2013 |
--------------------------

但我想单独为我的series1series2添加此内容。

(在我的现实生活中,我有许多国家和许多变数。)

所以我想得到:

-------------------------------------------------------------------------
| country | First.series1 | Last.series1 | First.series2 | Last.series2 |
-------------------------------------------------------------------------
| FRA     | 2005          | 2015         |  2012          | 2015        |
-------------------------------------------------------------------------
| USA     | 2006          | 2013         |  2003          | 2013        |
-------------------------------------------------------------------------

3 个答案:

答案 0 :(得分:4)

以下是我如何处理它:

df %>% 
  gather(series, value, starts_with("series")) %>% 
  filter(!is.na(value)) %>% 
  group_by(country, series) %>%
  summarize(First = min(year, na.rm = TRUE),
            Last  = max(year, na.rm = TRUE))

# A tibble: 4 x 4
# Groups:   country [?]
  country  series First  Last
    <chr>   <chr> <dbl> <dbl>
1     FRA series1  2005  2015
2     FRA series2  2012  2015
3     USA series1  2006  2013
4     USA series2  2003  2013

基本上我们将数据转换为长格式,过滤掉NA值,然后计算每个国家/地区和系列的最小/最大值。

答案 1 :(得分:4)

以下是使用data.table

的选项
library(data.table)
dcast(melt(setDT(df), id.var = c('year', 'country'), na.rm = TRUE)[, 
    .(First = min(year, na.rm = TRUE), Last = max(year, na.rm = TRUE)),
   .(country, variable)], country ~variable, value.var = c("First", "Last"), sep=".")
#   country First.series1 First.series2 Last.series1 Last.series2
#1:     FRA          2005          2012         2015         2015
#2:     USA          2006          2003         2013         2013

答案 2 :(得分:2)

我参加派对有点晚了,其他答案都很棒,但是如果你想坚持使用tidyverse和你指定格式的数据,请尝试以下方法:

library(tidyverse)

# Put the data in a tidy format
gathered_df <- df %>%
  gather(key = series_no, value = val, series1:series2, na.rm = TRUE)

# find the first and last by country and series
sum_df <- gathered_df %>%
  group_by(series_no, country) %>%
  summarise(Last = max(year),
            First = min(year))

# make min and max into a column, then add a label
# Eg First:series2
reduced_df <- sum_df %>%
  gather(key = measurement, value = year, First:Last) %>%
  mutate(label = factor(paste(series_no, ":", measurement))) %>%
  group_by(label) %>%
  select(label, year, country)

# Put the output in a table format as you wanted
output <- reduced_df %>%
  spread(key = label, value = year)