data.frame을 와이드 형식에서 롱 형식으로 재구성
변환하는 데 문제가 있습니다.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()
처리하기에 조금 더 좋아 보이기 때문에 기능.
두 가지 대안 솔루션:
data.table 사용:
다음 기능을 사용할 수 있습니다.
library(data.table)
long <- melt(setDT(wide), id.vars = c("Code","Country"), variable.name = "year")
이는 다음을 제공합니다.
> long 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
몇 가지 대체 표기법:
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")
티디르를 사용한 경우:
사용:
library(tidyr)
long <- wide %>%
pivot_longer(
cols = `1950`:`1954`,
names_to = "year",
values_to = "value"
)
참고:
names_to
그리고.values_to
에 결석한."name"
그리고."value"
각각, 그래서 당신은 이것을 특별히 명확하게 쓸 수 있습니다.wide %>% pivot_longer(`1950`:`1954`)
.- 그
cols
인수는 매우 유연한 깔끔한 선택 DSL을 사용하므로, 음의 선택을 사용하여 동일한 열을 선택할 수 있습니다.!c(Code, Country)
), 선택 도우미(starts_with("19")
;matches("^\\d{4}$")
), 숫자 인덱스(3:7
) 등을 참조하십시오. tidyr::pivot_longer()
의 후속 제품입니다.tidyr::gather()
그리고.reshape2::melt()
더 이상 개발 중이 아닌.
값 변환
데이터의 또 다른 문제는 값이 R에 의해 문자 값으로 읽혀진다는 것입니다.,
숫자로)으로 복구할 수 있습니다.gsub
그리고.as.numeric
모양을 바꾸기 전에:
long$value <- as.numeric(gsub(",", "", long$value))
또는 모양을 바꾸는 동안,data.table
또는tidyr
:
# data.table
long <- melt(setDT(wide),
id.vars = c("Code","Country"),
variable.name = "year")[, value := as.numeric(gsub(",", "", value))]
# tidyr
long <- wide %>%
pivot_longer(
cols = `1950`:`1954`,
names_to = "year",
values_to = "value",
values_transform = ~ as.numeric(gsub(",", "", .x))
)
데이터:
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()
익숙해지는 데 시간이 좀 걸립니다.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)
와 함께tidyr_1.0.0
또 다른 선택은pivot_longer
library(tidyr)
pivot_longer(df1, -c(Code, Country), values_to = "Value", names_to = "Year")
# A tibble: 10 x 4
# Code Country Year Value
# <fct> <fct> <chr> <fct>
# 1 AFG Afghanistan 1950 20,249
# 2 AFG Afghanistan 1951 21,352
# 3 AFG Afghanistan 1952 22,532
# 4 AFG Afghanistan 1953 23,557
# 5 AFG Afghanistan 1954 24,555
# 6 ALB Albania 1950 8,097
# 7 ALB Albania 1951 8,986
# 8 ALB Albania 1952 10,058
# 9 ALB Albania 1953 11,123
#10 ALB Albania 1954 12,246
데이터.
df1 <- structure(list(Code = structure(1:2, .Label = c("AFG", "ALB"), class = "factor"),
Country = structure(1:2, .Label = c("Afghanistan", "Albania"
), class = "factor"), `1950` = structure(1:2, .Label = c("20,249",
"8,097"), class = "factor"), `1951` = structure(1:2, .Label = c("21,352",
"8,986"), class = "factor"), `1952` = structure(2:1, .Label = c("10,058",
"22,532"), class = "factor"), `1953` = structure(2:1, .Label = c("11,123",
"23,557"), class = "factor"), `1954` = structure(2:1, .Label = c("12,246",
"24,555"), class = "factor")), class = "data.frame", row.names = c(NA,
-2L))
모양 바꾸기 패키지 사용:
#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
돌아온다TRUE
x가 이름 이외의 속성이 없는 지정된 모드의 벡터인 경우.돌아옵니다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
개별적으로 제거하거나(여기서 하는 것처럼) 원하는 연도를 명시적으로 포함하여 제거합니다.
쉼표를 처리하려면 다음과 같이 X를 추가합니다.check.names = FALSE
설정되지 않음), 저도 사용 중입니다.dplyr
의 변이는 변로하 다으다와 함께 합니다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. 그로텐디크가 그것을 실행해 준 것에 감사드립니다.
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
보다 정교한 방식으로 쿼리를 작성하려면 다음 게시물도 확인할 수 있습니다.
은 또한 있다니습수도를 할 수 .cdata
(테이블의 (으)ㄹ 수 있습니다.
# data
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)
library(cdata)
# build control table
drec <- data.frame(
Year=as.character(1950:1954),
Value=as.character(1950:1954),
stringsAsFactors=FALSE
)
drec <- cdata::rowrecs_to_blocks_spec(drec, recordKeys=c("Code", "Country"))
# apply control table
cdata::layout_by(drec, wide)
저는 현재 그 패키지를 탐색하고 있으며 꽤 접근성이 좋은 것으로 알고 있습니다.훨씬 더 복잡한 변환을 위해 설계되었으며 역변환을 포함합니다.사용 가능한 자습서가 있습니다.
언급URL : https://stackoverflow.com/questions/2185252/reshaping-data-frame-from-wide-to-long-format
'programing' 카테고리의 다른 글
선 끝에 레이블 표시 (0) | 2023.06.05 |
---|---|
세 개의 열 데이터 프레임을 행렬("긴"에서 "넓은" 형식)로 재구성 (0) | 2023.06.05 |
Android의 Firebase Google Authentication에서 사용자가 처음으로 인증되었는지 확인합니다. (0) | 2023.06.05 |
Android 플랫폼의 서비스 대 IntentService (0) | 2023.06.05 |
R이 지수 표기법(예: e+10)을 사용하지 않도록 강제합니까? (0) | 2023.06.05 |