我想知道我在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 |
--------------------------
但我想单独为我的series1
和series2
添加此内容。
(在我的现实生活中,我有许多国家和许多变数。)
所以我想得到:
-------------------------------------------------------------------------
| country | First.series1 | Last.series1 | First.series2 | Last.series2 |
-------------------------------------------------------------------------
| FRA | 2005 | 2015 | 2012 | 2015 |
-------------------------------------------------------------------------
| USA | 2006 | 2013 | 2003 | 2013 |
-------------------------------------------------------------------------
答案 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)