긴 형식에서 넓은 형식으로 데이터를 재구성하는 방법
다음 데이터 프레임을 다시 정렬하는 데 문제가 있습니다.
set.seed(45)
dat1 <- data.frame(
name = rep(c("firstName", "secondName"), each=4),
numbers = rep(1:4, 2),
value = rnorm(8)
)
dat1
name numbers value
1 firstName 1 0.3407997
2 firstName 2 -0.7033403
3 firstName 3 -0.3795377
4 firstName 4 -0.7460474
5 secondName 1 -0.8981073
6 secondName 2 -0.3347941
7 secondName 3 -0.5013782
8 secondName 4 -0.1745357
각 고유한 "이름" 변수가 행 이름이 되도록 모양을 변경하고, 행을 따라 "값"을 관측치로, "숫자"를 열 이름으로 지정합니다.이런 식입니다.
name 1 2 3 4
1 firstName 0.3407997 -0.7033403 -0.3795377 -0.7460474
5 secondName -0.8981073 -0.3347941 -0.5013782 -0.1745357
본적있습다니이▁at다니습▁i'를 살펴봤습니다.melt
그리고.cast
그리고 몇 가지 다른 것들도 있지만, 아무도 그 일을 할 수 없을 것 같습니다.
용사를 합니다.reshape
함수:
reshape(dat1, idvar = "name", timevar = "numbers", direction = "wide")
새로운것년2014 (2014년)tidyr
패키지는 또한 이것을 간단하게 합니다.gather()
/spread()
의 용어가 것melt
/cast
.
편집: 이제 2019년에 tidyr v 1.0이 시작되어 설정되었습니다.spread
그리고.gather
하지 않는 경로에서 사되지않경서에로는선, 대신호용▁instead를 합니다.pivot_wider
그리고.pivot_longer
이 답변에 설명된 내용을 확인할 수 있습니다.의 짧은 삶을 잠깐 들여다보고 싶다면 계속 읽어보세요.spread/gather
.
library(tidyr)
spread(dat1, key = numbers, value = value)
기트허브에서,
tidyr
는 의재입니다성구aming의 입니다.reshape2
정돈된 데이터 프레임워크와 함께 제공되며, 함께 작업할 수 있도록 설계되었습니다.magrittr
그리고.dplyr
데이터 분석을 위한 견고한 파이프라인 구축럼처입니다.
reshape2
모양을 바꾸는 것보다 덜 했습니다.tidyr
적은 수작행보다 적게 합니다.reshape2
데이터 정리를 위해 특별히 설계되었으며 일반적인 재구성이 아닙니다.reshape2
또는 재구성된 일반적인 집계가 수행했습니다.되며, 특히, 내장방식데프만적용며되에레임이터은,▁only▁in,적며되용,tidyr
마진이나 집계를 제공하지 않습니다.
은 이것을 을수수다있니습으로 할 수.reshape()
함수또사여와 melt()
/cast()
재구성 패키지의 함수입니다.두 코드는 " "입니다."입니다.
library(reshape)
cast(dat1, name ~ numbers)
는사용을 사용합니다.reshape2
library(reshape2)
dcast(dat1, name ~ numbers)
성능이 문제인 경우 다른 옵션은 다음을 사용하는 것은data.table
인 의장확.reshape2
의 멜트 & d캐스트 기능
(참조: data.table을 사용한 효율적인 재구성)
library(data.table)
setDT(dat1)
dcast(dat1, name ~ numbers, value.var = "value")
# name 1 2 3 4
# 1: firstName 0.1836433 -0.8356286 1.5952808 0.3295078
# 2: secondName -0.8204684 0.4874291 0.7383247 0.5757814
그리고 data.table v1.9.6 기준으로 여러 열에 캐스트할 수 있습니다.
## add an extra column
dat1[, value2 := value * 2]
## cast multiple value columns
dcast(dat1, name ~ numbers, value.var = c("value", "value2"))
# name value_1 value_2 value_3 value_4 value2_1 value2_2 value2_3 value2_4
# 1: firstName 0.1836433 -0.8356286 1.5952808 0.3295078 0.3672866 -1.6712572 3.190562 0.6590155
# 2: secondName -0.8204684 0.4874291 0.7383247 0.5757814 -1.6409368 0.9748581 1.476649 1.1515627
tidyr과함, 있다니께가 .pivot_wider()
그리고.pivot_longer()
그것들은 각각 긴 -> 넓은 또는 넓은 -> 긴 형태로 재구성하도록 일반화됩니다.OP의 데이터 사용:
단일 열 long -> wide
library(tidyr)
dat1 %>%
pivot_wider(names_from = numbers, values_from = value)
# # A tibble: 2 x 5
# name `1` `2` `3` `4`
# <fct> <dbl> <dbl> <dbl> <dbl>
# 1 firstName 0.341 -0.703 -0.380 -0.746
# 2 secondName -0.898 -0.335 -0.501 -0.175
여러 열 길이 -> 너비
pivot_wider()
또한 보다 복잡한 피벗 작업도 수행할 수 있습니다.예를 들어, 여러 열을 동시에 피벗할 수 있습니다.
# create another column for showing the functionality
dat2 <- dat1 %>%
dplyr::rename(valA = value) %>%
dplyr::mutate(valB = valA * 2)
dat2 %>%
pivot_wider(names_from = numbers, values_from = c(valA, valB))
# # A tibble: 2 × 9
# name valA_1 valA_2 valA_3 valA_4 valB_1 valB_2 valB_3 valB_4
# <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 firstName 0.341 -0.703 -0.380 -0.746 0.682 -1.41 -0.759 -1.49
# 2 secondName -0.898 -0.335 -0.501 -0.175 -1.80 -0.670 -1.00 -0.349
문서에는 훨씬 더 많은 기능이 있습니다.
예제 데이터 프레임을 사용하면 다음과 같은 이점을 얻을 수 있습니다.
xtabs(value ~ name + numbers, data = dat1)
기타 두 가지 옵션:
기본 패키지:
df <- unstack(dat1, form = value ~ numbers)
rownames(df) <- unique(dat1$name)
df
sqldf
패키지:
library(sqldf)
sqldf('SELECT name,
MAX(CASE WHEN numbers = 1 THEN value ELSE NULL END) x1,
MAX(CASE WHEN numbers = 2 THEN value ELSE NULL END) x2,
MAX(CASE WHEN numbers = 3 THEN value ELSE NULL END) x3,
MAX(CASE WHEN numbers = 4 THEN value ELSE NULL END) x4
FROM dat1
GROUP BY name')
R 사용하기 R 준용 R 사aggregate
함수:
aggregate(value ~ name, dat1, I)
# name value.1 value.2 value.3 value.4
#1 firstName 0.4145 -0.4747 0.0659 -0.5024
#2 secondName -0.8259 0.1669 -0.8962 0.1681
베스이reshape
기능이 완벽하게 정상적으로 작동합니다.
df <- data.frame(
year = c(rep(2000, 12), rep(2001, 12)),
month = rep(1:12, 2),
values = rnorm(24)
)
df_wide <- reshape(df, idvar="year", timevar="month", v.names="values", direction="wide", sep="_")
df_wide
어디에
idvar
입니다.timevar
캐스팅할 입니다.v.names
는 숫자 있는 입니다.direction
long 합니다.- 사항인 택사항
sep
는 사이사구기다니분호입는용 사이에 입니다.timevar
및 클래스 이름v.names
됩니다.data.frame
.
안되면idvar
를 사용하기 전에reshape()
함수:
df$id <- c(rep("year1", 12), rep("year2", 12))
df_wide <- reshape(df, idvar="id", timevar="month", v.names="values", direction="wide", sep="_")
df_wide
.idvar
필수 항목입니다! 그timevar
그리고.v.names
부분은 쉽습니다.모든 것이 명시적으로 정의되어 있기 때문에 이 함수의 출력은 다른 함수보다 더 예측 가능합니다.
Win-Vector를 만든 )의 이 보낸 vtreat
,seplyr
그리고.replyr
라는 이름의cdata
이 문서와 블로그 게시물에 설명된 "조정된 데이터" 원칙을 구현합니다.데이터를 어떻게 구성하든 "데이터 좌표" 시스템을 사용하여 개별 데이터 지점을 식별할 수 있어야 합니다.다음은 John Mount의 최근 블로그 게시물에서 발췌한 내용입니다.
전체 시스템은 두 개의 원시 또는 연산자 cdata:moveValuesToRowsD()와 cdata::moveValuesToColumnsD()를 기반으로 합니다.이러한 연산자는 피벗, 피벗, 원핫 인코딩, 전치, 여러 행 및 열 이동 및 기타 많은 변환을 단순한 특수한 경우로 사용합니다.
cdata 프리미티브 측면에서 다양한 연산을 작성하는 것은 쉽습니다.이러한 연산자는 메모리 또는 빅데이터 규모로 작업할 수 있습니다(데이터베이스 및 Apache Spark 사용). 빅데이터의 경우 cdata::moveValuesToRowsN() 및 cdata:::moveValuesToColumnsN() 변형을 사용합니다.변환은 변환의 다이어그램(또는 그림)인 제어 테이블에 의해 제어됩니다.
먼저 제어 테이블을 작성한 다음(자세한 내용은 블로그 게시물 참조) 행에서 열로 데이터 이동을 수행합니다.
library(cdata)
# first build the control table
pivotControlTable <- buildPivotControlTableD(table = dat1, # reference to dataset
columnToTakeKeysFrom = 'numbers', # this will become column headers
columnToTakeValuesFrom = 'value', # this contains data
sep="_") # optional for making column names
# perform the move of data to columns
dat_wide <- moveValuesToColumnsD(tallTable = dat1, # reference to dataset
keyColumns = c('name'), # this(these) column(s) should stay untouched
controlTable = pivotControlTable# control table above
)
dat_wide
#> name numbers_1 numbers_2 numbers_3 numbers_4
#> 1 firstName 0.3407997 -0.7033403 -0.3795377 -0.7460474
#> 2 secondName -0.8981073 -0.3347941 -0.5013782 -0.1745357
훨씬 쉬운 방법!
devtools::install_github("yikeshu0611/onetree") #install onetree package
library(onetree)
widedata=reshape_toWide(data = dat1,id = "name",j = "numbers",value.var.prefix = "value")
widedata
name value1 value2 value3 value4
firstName 0.3407997 -0.7033403 -0.3795377 -0.7460474
secondName -0.8981073 -0.3347941 -0.5013782 -0.1745357
와이드에서 롱으로 되돌리려면 와이드만 롱으로 변경하고 오브젝트는 변경하지 마십시오.
reshape_toLong(data = widedata,id = "name",j = "numbers",value.var.prefix = "value")
name numbers value
firstName 1 0.3407997
secondName 1 -0.8981073
firstName 2 -0.7033403
secondName 2 -0.3347941
firstName 3 -0.3795377
secondName 3 -0.5013782
firstName 4 -0.7460474
secondName 4 -0.1745357
정렬이하지 않은 합니다.as.matrix(dat1)[,1:2]
는 대할수있니다습체로 할 수 있습니다.cbind(dat1[,1],dat1[,2])
):
> set.seed(45);dat1=data.frame(name=rep(c("firstName","secondName"),each=4),numbers=rep(1:4,2),value=rnorm(8))
> u1=unique(dat1[,1]);u2=unique(dat1[,2])
> m=matrix(nrow=length(u1),ncol=length(u2),dimnames=list(u1,u2))
> m[as.matrix(dat1)[,1:2]]=dat1[,3]
> m
1 2 3 4
firstName 0.3407997 -0.7033403 -0.3795377 -0.7460474
secondName -0.8981073 -0.3347941 -0.5013782 -0.1745357
누락된 쌍이 있고 정렬이 필요한 경우에는 이 방법이 작동하지 않지만, 쌍이 이미 정렬된 경우에는 이 방법이 조금 더 짧습니다.
> u1=unique(dat1[,1]);u2=unique(dat1[,2])
> dat1=dat1[order(dat1[,1],dat1[,2]),] # not actually needed in this case
> matrix(dat1[,3],length(u1),,T,list(u1,u2))
1 2 3 4
firstName 0.3407997 -0.7033403 -0.3795377 -0.7460474
secondName -0.8981073 -0.3347941 -0.5013782 -0.1745357
번째as.data.frame
경골과 함께 작동하도록 하기 위해):
l2w=function(x,row=1,col=2,val=3,sort=F){
u1=unique(x[,row])
u2=unique(x[,col])
if(sort){u1=sort(u1);u2=sort(u2)}
out=matrix(nrow=length(u1),ncol=length(u2),dimnames=list(u1,u2))
out[cbind(x[,row],x[,col])]=x[,val]
out
}
또는 아래쪽 삼각형 값만 있는 경우 다음 작업을 수행할 수 있습니다.
> euro=as.matrix(eurodist)[1:3,1:3]
> lower=data.frame(V1=rownames(euro)[row(euro)[lower.tri(euro)]],V2=colnames(euro)[col(euro)[lower.tri(euro)]],V3=euro[lower.tri(euro)])
> lower
V1 V2 V3
1 Barcelona Athens 3313
2 Brussels Athens 2963
3 Brussels Barcelona 1318
> n=unique(c(lower[,1],lower[,2]))
> full=rbind(lower,setNames(lower[,c(2,1,3)],names(lower)),data.frame(V1=n,V2=n,V3=0))
> full
V1 V2 V3
1 Barcelona Athens 3313
2 Brussels Athens 2963
3 Brussels Barcelona 1318
4 Athens Barcelona 3313
5 Athens Brussels 2963
6 Barcelona Brussels 1318
7 Athens Athens 0
8 Barcelona Barcelona 0
9 Brussels Brussels 0
> l2w(full,sort=T)
Athens Barcelona Brussels
Athens 0 3313 2963
Barcelona 3313 0 1318
Brussels 2963 1318 0
또는 다른 접근 방식이 있습니다.
> rc=as.matrix(lower[-3])
> n=sort(unique(c(rc)))
> m=matrix(0,length(n),length(n),,list(n,n))
> m[rc]=lower[,3]
> m[rc[,2:1]]=lower[,3]
> m
Athens Barcelona Brussels
Athens 0 3313 2963
Barcelona 3313 0 1318
Brussels 2963 1318 0
또은 기의본또간방다같법습다니음과은한단른다다▁another▁in같니습▁to▁use▁r를 사용하는 것입니다.xtabs
의 결과xtabs
기본적으로 화려한 클래스 이름을 가진 행렬이지만, 당신은 그것을 정규 행렬처럼 만들 수 있습니다.class(x)=NULL;attr(x,"call")=NULL;dimnames(x)=unname(dimnames(x))
:
> x=xtabs(value~name+numbers,dat1);x
numbers
name 1 2 3 4
firstName 0.3407997 -0.7033403 -0.3795377 -0.7460474
secondName -0.8981073 -0.3347941 -0.5013782 -0.1745357
> str(x)
'xtabs' num [1:2, 1:4] 0.341 -0.898 -0.703 -0.335 -0.38 ...
- attr(*, "dimnames")=List of 2
..$ name : chr [1:2] "firstName" "secondName"
..$ numbers: chr [1:4] "1" "2" "3" "4"
- attr(*, "call")= language xtabs(formula = value ~ name + numbers, data = dat1)
> class(x)
[1] "xtabs" "table"
> class(as.matrix(x)) # `as.matrix` has no effect because `x` is already a matrix
[1] "xtabs" "table"
> class(x)=NULL;class(x)
[1] "matrix" "array"
> attr(x,"call")=NULL;dimnames(x)=unname(dimnames(x))
> x # now it looks like a regular matrix
1 2 3 4
firstName 0.3407997 -0.7033403 -0.3795377 -0.7460474
secondName -0.8981073 -0.3347941 -0.5013782 -0.1745357
> str(x)
num [1:2, 1:4] 0.341 -0.898 -0.703 -0.335 -0.38 ...
- attr(*, "dimnames")=List of 2
..$ : chr [1:2] "firstName" "secondName"
..$ : chr [1:4] "1" "2" "3" "4"
은 통보.as.data.frame(x)
변다환의 결과를 합니다.xtabs
형식으로 , 긴형으돌지만아사, 는이수있다피니습할를가자용으로 피할 수 .class(x)=NULL
:
> x=xtabs(value~name+numbers,dat1);as.data.frame(x)
name numbers Freq
1 firstName 1 0.3407997
2 secondName 1 -0.8981073
3 firstName 2 -0.7033403
4 secondName 2 -0.3347941
5 firstName 3 -0.3795377
6 secondName 3 -0.5013782
7 firstName 4 -0.7460474
8 secondName 4 -0.1745357
> class(x)=NULL;as.data.frame(x)
1 2 3 4
firstName 0.3407997 -0.7033403 -0.3795377 -0.7460474
secondName -0.8981073 -0.3347941 -0.5013782 -0.1745357
형식으로가 변환됩니다.unlist
로 변환합니다.c
행렬을 벡터로 변환):
w2l=function(x)data.frame(V1=rownames(x)[row(x)],V2=colnames(x)[col(x)],V3=unname(c(unlist(x))))
세 개의 열 데이터 프레임을 행렬로 재구성("긴"에서 "넓은" 형식)하는 링크된 질문을 통해 여기에 왔습니다.그 질문은 종결되었으므로 저는 여기에 대안을 작성합니다.
저는 세 개의 열을 행렬로 변환하려는 사람에게 유용한 대안을 찾았습니다.디커플R(2.3.2) 패키지를 말하는 것입니다.아래는 해당 사이트에서 복사한 것입니다.
행이 id_cols, 열이 names_from 및 값이 values_from인 테이블 종류를 생성합니다.
사용.
pivot_wider_profile(
data,
id_cols,
names_from,
values_from,
values_fill = NA,
to_matrix = FALSE,
to_sparse = FALSE,
...
)
만 사용dplyr
그리고.map
.
library(dplyr)
library(purrr)
set.seed(45)
dat1 <- data.frame(
name = rep(c("firstName", "secondName"), each=4),
numbers = rep(1:4, 2), value = rnorm(8)
)
longer_to_wider <- function(data, name_from, value_from){
group <- colnames(data)[!(colnames(data) %in% c(name_from,value_from))]
data %>% group_by(.data[[group]]) %>%
summarise( name = list(.data[[name_from]]),
value = list(.data[[value_from]])) %>%
{
d <- data.frame(
name = .[[name_from]] %>% unlist() %>% unique()
)
e <- map_dfc(.[[group]],function(x){
y <- data_frame(
x = data %>% filter(.data[[group]] == x) %>% pull(value_from)
)
colnames(y) <- x
y
})
cbind(d,e)
}
}
longer_to_wider(dat1, "name", "value")
# name 1 2 3 4
# 1 firstName 0.3407997 -0.7033403 -0.3795377 -0.7460474
# 2 secondName -0.8981073 -0.3347941 -0.5013782 -0.1745357
언급URL : https://stackoverflow.com/questions/5890584/how-to-reshape-data-from-long-to-wide-format
'programing' 카테고리의 다른 글
GCC의 __attribute__(...) 구문이 이중 괄호를 사용하는 이유는 무엇입니까? (0) | 2023.06.30 |
---|---|
코드의 최신 버전을 얻으려면 어떻게 해야 합니까? (0) | 2023.06.30 |
@Springboot의 값이 null을 반환합니다. (0) | 2023.06.30 |
pip3로 패키지를 설치할 때 "Python에서 ssl 모듈을 사용할 수 없습니다. (0) | 2023.06.30 |
.gitignore를 사용하여 특정 디렉터리를 제외한 모든 항목 무시 (0) | 2023.06.30 |