この問題に対するベース R のreshape
アプローチは、特に名前がreshape
好きな形式ではないため、かなり醜いです。次のようになります。最初のsetNames
行は、列名をreshape
利用できるものに変更します。
reshape(
setNames(mydf, c("Country", paste0("val.", c(2001, 2002, 2003)))),
direction = "long", idvar = "Country", varying = 2:ncol(mydf),
sep = ".", new.row.names = seq_len(prod(dim(mydf[-1]))))
ベース R でのより良い代替手段はstack
、次のように を使用することです。
cbind(mydf[1], stack(mydf[-1]))
# Country values ind
# 1 Nigeria 1 2001
# 2 UK 2 2001
# 3 Nigeria 2 2002
# 4 UK NA 2002
# 5 Nigeria 3 2003
# 6 UK 1 2003
「tidyr」パッケージなど、データを再形成するための新しいツールも利用できるようになりましたgather
。もちろん、このtidyr:::gather_.data.frame
メソッドは を呼び出すだけreshape2::melt
なので、Hadleyverse で遭遇する可能性のある新しい構文を紹介することを除いて、私の回答のこの部分は必ずしも多くを追加するわけではありません。
library(tidyr)
gather(mydf, year, value, `2001`:`2003`) ## Note the backticks
# Country year value
# 1 Nigeria 2001 1
# 2 UK 2001 2
# 3 Nigeria 2002 2
# 4 UK 2002 NA
# 5 Nigeria 2003 3
# 6 UK 2003 1
質問で示した行の順序が必要な場合は、ここでの 3 つのオプションすべてで行の並べ替えが必要になります。
4 番目のオプションはmerged.stack
、私の「splitstackshape」パッケージから使用することです。ベース R のreshape
ように、列名を「変数」および「時間」インジケーターを含む名前に変更する必要があります。
library(splitstackshape)
merged.stack(
setNames(mydf, c("Country", paste0("V.", 2001:2003))),
var.stubs = "V", sep = ".")
# Country .time_1 V
# 1: Nigeria 2001 1
# 2: Nigeria 2002 2
# 3: Nigeria 2003 3
# 4: UK 2001 2
# 5: UK 2002 NA
# 6: UK 2003 1
サンプルデータ
mydf <- structure(list(Country = c("Nigeria", "UK"), `2001` = 1:2, `2002` = c(2L,
NA), `2003` = c(3L, 1L)), .Names = c("Country", "2001", "2002",
"2003"), row.names = 1:2, class = "data.frame")