创建具有相同变量的多个子集的新数据框

时间:2018-09-08 20:09:32

标签: r dplyr

我想创建一个新的数据框,其中的列是同一变量的子集,这些子集由不同的变量拆分。例如,我想创建一个新的变量('b')子集,其中各列由另一个变量('year')的子集分隔

set.seed(88)
df <- data.frame(year = rep(1996:1998,3), a = runif(9), b = runif(9), e = runif(9)) 
df

  year          a          b         e
1 1996 0.41050128 0.97679183 0.7477684
2 1997 0.10273570 0.54925568 0.7627982
3 1998 0.74104481 0.74416429 0.2114261
4 1996 0.48007870 0.55296210 0.7377032
5 1997 0.99051343 0.18097104 0.8404930
6 1998 0.99954223 0.02063662 0.9153588
7 1996 0.03247379 0.33055434 0.9182541
8 1997 0.76020784 0.10246882 0.7055694
9 1998 0.67713100 0.59292207 0.4093590

1996年和1998年变量'b'的期望输出为:

         V1         V2
1 0.9767918 0.74416429
2 0.5529621 0.02063662
3 0.3305543 0.59292207

我可能会找到一种通过循环执行此操作的方法,但我想知道是否存在dplyr方法(或任何简单的方法来完成此操作)。

2 个答案:

答案 0 :(得分:4)

我们基于1996年,1998年的{year},subset的'year','b'列和select的{​​{1}}数据集来获得预期的输出结果

unstack

或者使用unstack(subset(df, year %in% c(1996, 1998), select = c('year', 'b')), b ~ year) # X1996 X1998 #1 0.9767918 0.74416429 #2 0.5529621 0.02063662 #@3 0.3305543 0.59292207 ,我们tidyverse感兴趣的列,select基于'year'列的行,按'year'创建序列列,{{1} }设置为“宽”格式,并filter删除不需要的列

spread

由于只有两年,因此我们也可以使用select

library(tidyverse)
df %>% 
   select(year, b) %>% 
   filter(year %in% c(1996, 1998)) %>%
   group_by(year = factor(year, levels = unique(year), labels = c('V1', 'V2'))) %>% 
   mutate(n = row_number()) %>%
   spread(year, b) %>%
   select(-n)
# A tibble: 3 x 2   
#     V1     V2
#   <dbl>  <dbl>
#1 0.977 0.744 
#2 0.553 0.0206
#3 0.331 0.593 

答案 1 :(得分:2)

使用dplyr的另一个选项,它混合了一些基数R,导致解决方案比@akrun的代码短了

bind_cols(split(df$b, df$year)) %>% select(-'1997')

# A tibble: 3 x 2
  `1996` `1998`
   <dbl>  <dbl>
1  0.977 0.744 
2  0.553 0.0206
3  0.331 0.593