data.frame
を幅の広いテーブルから長いテーブルに変換するのに苦労しています。現時点では次のようになっています。
Code Country 1950 1951 1952 1953 1954
AFG Afghanistan 20,249 21,352 22,532 23,557 24,555
ALB Albania 8,097 8,986 10,058 11,123 12,246
次に、このdata.frame
を長いdata.frame
に変換したいと思います。このようなもの:
Code Country Year Value
AFG Afghanistan 1950 20,249
AFG Afghanistan 1951 21,352
AFG Afghanistan 1952 22,532
AFG Afghanistan 1953 23,557
AFG Afghanistan 1954 24,555
ALB Albania 1950 8,097
ALB Albania 1951 8,986
ALB Albania 1952 10,058
ALB Albania 1953 11,123
ALB Albania 1954 12,246
一部の人々が同様の質問で提案しているように、私はmelt()
およびreshape()
関数を調べて使用してみました。しかし、これまでのところ、私は面倒な結果しか得られません。
可能であれば、reshape()
関数を使用して処理したいと思います。
reshape()
は、melt
/cast
と同様、慣れるまでに時間がかかります。以下は、データフレームの名前がd
であると仮定して、形状を変更するソリューションです。
reshape(d, direction = "long", varying = list(names(d)[3:7]), v.names = "Value",
idvar = c("Code","Country"), timevar = "Year", times = 1950:1954)
3つの代替ソリューション:
1:With reshape2
library(reshape2)
long <- melt(wide, id.vars = c("Code", "Country"))
与える:
Code Country variable value
1 AFG Afghanistan 1950 20,249
2 ALB Albania 1950 8,097
3 AFG Afghanistan 1951 21,352
4 ALB Albania 1951 8,986
5 AFG Afghanistan 1952 22,532
6 ALB Albania 1952 10,058
7 AFG Afghanistan 1953 23,557
8 ALB Albania 1953 11,123
9 AFG Afghanistan 1954 24,555
10 ALB Albania 1954 12,246
同じ結果を与えるいくつかの代替表記法:
# you can also define the id-variables by column number
melt(wide, id.vars = 1:2)
# as an alternative you can also specify the measure-variables
# all other variables will then be used as id-variables
melt(wide, measure.vars = 3:7)
melt(wide, measure.vars = as.character(1950:1954))
2:data.table
を使用
reshape2
パッケージ(拡張および改善された実装)と同じmelt
関数を使用できます。 melt
from data.table
には、reshape2
からのmelt
- functionよりも多くのパラメーターもあります。たとえば、変数列の名前を指定することもできます。
library(data.table)
long <- melt(setDT(wide), id.vars = c("Code","Country"), variable.name = "year")
いくつかの代替表記法:
melt(setDT(wide), id.vars = 1:2, variable.name = "year")
melt(setDT(wide), measure.vars = 3:7, variable.name = "year")
melt(setDT(wide), measure.vars = as.character(1950:1954), variable.name = "year")
:tidyr
あり
library(tidyr)
long <- wide %>% gather(year, value, -c(Code, Country))
いくつかの代替表記法:
wide %>% gather(year, value, -Code, -Country)
wide %>% gather(year, value, -1:-2)
wide %>% gather(year, value, -(1:2))
wide %>% gather(year, value, -1, -2)
wide %>% gather(year, value, 3:7)
wide %>% gather(year, value, `1950`:`1954`)
NA
値を除外する場合、melt
関数とgather
関数にna.rm = TRUE
を追加できます。
データに関する別の問題は、Rが値を文字値として読み取ることです(数字の,
の結果)。 gsub
とas.numeric
で修復できます:
long$value <- as.numeric(gsub(",", "", long$value))
または、data.table
またはdplyr
で直接:
# data.table
long <- melt(setDT(wide),
id.vars = c("Code","Country"),
variable.name = "year")[, value := as.numeric(gsub(",", "", value))]
# tidyr and dplyr
long <- wide %>% gather(year, value, -c(Code,Country)) %>%
mutate(value = as.numeric(gsub(",", "", value)))
データ:
wide <- read.table(text="Code Country 1950 1951 1952 1953 1954
AFG Afghanistan 20,249 21,352 22,532 23,557 24,555
ALB Albania 8,097 8,986 10,058 11,123 12,246", header=TRUE, check.names=FALSE)
reshapeパッケージを使用:
#data
x <- read.table(textConnection(
"Code Country 1950 1951 1952 1953 1954
AFG Afghanistan 20,249 21,352 22,532 23,557 24,555
ALB Albania 8,097 8,986 10,058 11,123 12,246"), header=TRUE)
library(reshape)
x2 <- melt(x, id = c("Code", "Country"), variable_name = "Year")
x2[,"Year"] <- as.numeric(gsub("X", "" , x2[,"Year"]))
この回答には r-faq のタグが付けられているため、ベースRから別の代替案を共有すると便利だと感じました:stack
。
ただし、stack
はfactor
sでは機能しないことに注意してください。is.vector
がTRUE
である場合にのみ機能し、is.vector
のドキュメントから、それ:
is.vector
は、xが属性を持たない指定されたモードのベクトルである場合、TRUE
を返します名前以外。それ以外の場合はFALSE
を返します。
サンプルデータ @ Jaapの回答から を使用しています。ここで、年の列の値はfactor
sです。
stack
アプローチは次のとおりです。
cbind(wide[1:2], stack(lapply(wide[-c(1, 2)], as.character)))
## Code Country values ind
## 1 AFG Afghanistan 20,249 1950
## 2 ALB Albania 8,097 1950
## 3 AFG Afghanistan 21,352 1951
## 4 ALB Albania 8,986 1951
## 5 AFG Afghanistan 22,532 1952
## 6 ALB Albania 10,058 1952
## 7 AFG Afghanistan 23,557 1953
## 8 ALB Albania 11,123 1953
## 9 AFG Afghanistan 24,555 1954
## 10 ALB Albania 12,246 1954
gather
からのtidyr
の使用を示す別の例です。 gather
の列を選択するには、個別に削除するか(ここで行うように)、必要な年を明示的に含めます。
コンマ(およびcheck.names = FALSE
が設定されていない場合はXを追加)を処理するために、dplyr
のmutateをparse_number
からreadr
に変換して、テキスト値を元に戻すことに注意してください数字に。これらはすべてtidyverse
の一部であるため、library(tidyverse)
と一緒にロードできます。
wide %>%
gather(Year, Value, -Code, -Country) %>%
mutate(Year = parse_number(Year)
, Value = parse_number(Value))
返却値:
Code Country Year Value
1 AFG Afghanistan 1950 20249
2 ALB Albania 1950 8097
3 AFG Afghanistan 1951 21352
4 ALB Albania 1951 8986
5 AFG Afghanistan 1952 22532
6 ALB Albania 1952 10058
7 AFG Afghanistan 1953 23557
8 ALB Albania 1953 11123
9 AFG Afghanistan 1954 24555
10 ALB Albania 1954 12246
sqldf のソリューションは次のとおりです。
sqldf("Select Code, Country, '1950' As Year, `1950` As Value From wide
Union All
Select Code, Country, '1951' As Year, `1951` As Value From wide
Union All
Select Code, Country, '1952' As Year, `1952` As Value From wide
Union All
Select Code, Country, '1953' As Year, `1953` As Value From wide
Union All
Select Code, Country, '1954' As Year, `1954` As Value From wide;")
すべてを入力せずにクエリを作成するには、次を使用できます。
G。Grothendieck を実装してくれてありがとう。
ValCol <- tail(names(wide), -2)
s <- sprintf("Select Code, Country, '%s' As Year, `%s` As Value from wide", ValCol, ValCol)
mquery <- paste(s, collapse = "\n Union All\n")
cat(mquery) #just to show the query
# Select Code, Country, '1950' As Year, `1950` As Value from wide
# Union All
# Select Code, Country, '1951' As Year, `1951` As Value from wide
# Union All
# Select Code, Country, '1952' As Year, `1952` As Value from wide
# Union All
# Select Code, Country, '1953' As Year, `1953` As Value from wide
# Union All
# Select Code, Country, '1954' As Year, `1954` As Value from wide
sqldf(mquery)
# Code Country Year Value
# 1 AFG Afghanistan 1950 20,249
# 2 ALB Albania 1950 8,097
# 3 AFG Afghanistan 1951 21,352
# 4 ALB Albania 1951 8,986
# 5 AFG Afghanistan 1952 22,532
# 6 ALB Albania 1952 10,058
# 7 AFG Afghanistan 1953 23,557
# 8 ALB Albania 1953 11,123
# 9 AFG Afghanistan 1954 24,555
# 10 ALB Albania 1954 12,246
残念ながら、PIVOT
とUNPIVOT
はR
SQLite
に対して機能するとは思わない。クエリをより洗練された方法で作成する場合は、次の投稿もご覧ください。