我想创建一个新的数据框,其中的列是同一变量的子集,这些子集由不同的变量拆分。例如,我想创建一个新的变量('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方法(或任何简单的方法来完成此操作)。
答案 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