パネル構造のデータフレームがあります。2年間のユニットごとに2つの観測値:
library(tidyr)
mydf <- data.frame(
id = rep(1:3, rep(2,3)),
year = rep(c(2012, 2013), 3),
value = runif(6)
)
mydf
# id year value
#1 1 2012 0.09668064
#2 1 2013 0.62739399
#3 2 2012 0.45618433
#4 2 2013 0.60347152
#5 3 2012 0.84537624
#6 3 2013 0.33466030
このデータをtidyr::spread
で簡単に実行できるワイドフォーマットに再形成したいと思います。ただし、year
変数の値は数値であるため、新しい変数の名前も数値になり、それ以上の使用が難しくなります。
spread(mydf, year, value)
# id 2012 2013
#1 1 0.09668064 0.6273940
#2 2 0.45618433 0.6034715
#3 3 0.84537624 0.3346603
列の名前を簡単に変更できることはわかっています。ただし、他の操作でチェーン内の形状を変更したい場合は不便になります。例えば。次の行は明らかに意味がありません。
library(dplyr)
mydf %>% spread(year, value) %>% filter(2012 > 0.5)
以下は機能しますが、それほど簡潔ではありません。
tmp <- spread(mydf, year, value)
names(tmp) <- c("id", "y2012", "y2013")
filter(tmp, y2012 > 0.5)
spread
内の新しい変数名を変更する方法はありますか?
この質問が最初に行われてから数年が経過したことは知っていますが、後世のために、sep
のspread
引数も強調したいと思います。 NULL
でない場合は、キー名と値の間の区切り文字として使用されます。
mydf %>%
spread(key = year, value = value, sep = "")
# id year2012 year2013
#1 1 0.15608322 0.6886531
#2 2 0.04598124 0.0792947
#3 3 0.16835445 0.1744542
これは質問で望んでいたとおりではありませんが、私の目的には十分です。 ?spread
を参照してください。
tidyr 1.0.0で更新:tidyr1.0.0ではpivot_wider
(およびpivot_longer
)が導入され、引数names_sep
に関してこの点でより詳細な制御が可能になりました。およびnames_prefix
。したがって、呼び出しは次のようになります。
mydf %>%
pivot_wider(names_from = year, values_from = value,
names_prefix = "year")
# # A tibble: 3 x 3
# id year2012 year2013
# <int> <dbl> <dbl>
# 1 1 0.347 0.388
# 2 2 0.565 0.924
# 3 3 0.406 0.296
当初必要だったものを正確に取得するには(接頭辞「y」のみ)、もちろん、names_prefix = "y"
を指定するだけで直接取得できます。
names_sep
は、データに四半期を追加した以下に示すように、複数の列にまたがって収集する場合に使用されます。
# Add quarters to data
mydf2 <- data.frame(
id = rep(1:3, each = 8),
year = rep(rep(c(2012, 2013), each = 4), 3),
quarter = rep(c("Q1","Q2","Q3","Q4"), 3),
value = runif(24)
)
head(mydf2)
# id year quarter value
# 1 1 2012 Q1 0.8651470
# 2 1 2012 Q2 0.3944423
# 3 1 2012 Q3 0.4580580
# 4 1 2012 Q4 0.2902604
# 5 1 2013 Q1 0.4751588
# 6 1 2013 Q2 0.6851755
mydf2 %>%
pivot_wider(names_from = c(year, quarter), values_from = value,
names_sep = "_", names_prefix = "y")
# # A tibble: 3 x 9
# id y2012_Q1 y2012_Q2 y2012_Q3 y2012_Q4 y2013_Q1 y2013_Q2 y2013_Q3 y2013_Q4
# <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 1 0.865 0.394 0.458 0.290 0.475 0.685 0.213 0.920
# 2 2 0.566 0.614 0.509 0.0515 0.974 0.916 0.681 0.509
# 3 3 0.968 0.615 0.670 0.748 0.723 0.996 0.247 0.449
数字で始まる列名にはbackticks
を使用でき、filter
は期待どおりに機能するはずです
mydf %>%
spread(year, value) %>%
filter(`2012` > 0.5)
# id 2012 2013
#1 3 0.8453762 0.3346603
または、別のオプションは、unite
を使用して、文字列「y」で2番目の列「year1」を作成した後に2つの列を1つの列に結合することです。
mydf %>%
mutate(year1='y') %>%
unite(yearN, year1, year) %>%
spread(yearN, value) %>%
filter(y_2012 > 0.5)
# id y_2012 y_2013
#1 3 0.8453762 0.3346603
mutate
を使用して、paste
内の「年」列を変更することもできます。
mydf %>%
mutate(year=paste('y', year, sep="_")) %>%
spread(year, value) %>%
filter(y_2012 > 0.5)
もう1つのオプションは、パイプ内の次のものとしてsetNames()
関数を使用することです。
_mydf %>%
spread(mydf, year, value) %>%
setNames( c("id", "y2012", "y2013") ) %>%
filter(y2012 > 0.5)
_
SetNamesを使用する場合の唯一の問題は、列をspread()
するときに列がどうなるかを正確に知る必要があることです。ほとんどの場合、特に半対話的に作業している場合は、それは問題ではありません。
ただし、元のデータにキーと値のペアがない場合は、列として表示されない可能性があり、知らないうちに列に誤った名前を付ける可能性があります。確かに、setNames()
は、名前の数が列の数と一致しない場合にエラーをスローするため、エラーチェックが組み込まれています。
それでも、setNames()
を使用することの便利さは、私にとってリスクを上回っています。
spread()
の後継であるpivot_wider()
を使用して、作成された列にプレフィックスを付けることができます。
library(tidyr)
set.seed(1)
mydf <- data.frame(
id = rep(1:3, rep(2,3)),
year = rep(c(2012, 2013), 3),
value = runif(6)
)
pivot_wider(mydf, names_from = "year", values_from = "value", names_prefix = "y")
#> # A tibble: 3 x 3
#> id y2012 y2013
#> <int> <dbl> <dbl>
#> 1 1 0.266 0.372
#> 2 2 0.573 0.908
#> 3 3 0.202 0.898
2019-09-14に reprexパッケージ (v0.3.0)によって作成されました
dplyrのrename()でうまくいくはずです
library(tidyr); library(dplyr)
mydf %>%
spread(year,value)%>%
rename(y2012 = '2012',y2013 = '2013')%>%
filter(y2012>0.5)