15 min to read
R-Studio 전처리 dcast/melt 사용하기
R-Studio의 전처리함수 dcast/melt 함수.
R-Studio 도 함수를 만들 수 있다.
전처리를 위해 reshape2 패키지를 이용 한다.
사용된 함수
함수이름 |
---|
dcast() / melt() |
파일 소스
우클릭 -> 다른이름으로 링크저장 이용해 주세요
examtest.csv
data.csv
wide.csv
students.csv
fruits_10.csv
pay_data.csv
사용 예시 소스코드
install.packages("reshape2")
library(reshape2)
mytest <- read.csv("examtest.csv", header = T)
mytest
# names gender korean english math computer science
# 1 강감찬 M 85 77 80 100 96
# 2 이순신 M 86 90 82 93 93
# 3 신사임당 F 80 98 87 92 90
# 4 서현진 F 97 87 80 85 80
# 5 전지현 F 100 100 98 100 94
# 6 김유신 M 56 58 80 92 60
# 7 을지문덕 M 88 88 90 79 87
# 8 이효리 F 48 59 60 50 54
# 9 김구 M 70 66 70 80 73
# 10 안중근 M 40 92 56 40 45
# 11 황신혜 F 46 76 79 46 50
# 12 계백 M 58 88 62 58 60
# 13 황진이 F 78 89 80 76 71
# 14 김고은 F 77 80 70 78 73
# 15 이만기 M 79 82 88 80 78
# 16 이상순 M 95 89 89 90 97
# 17 박보검 M 97 94 88 90 91
# 18 김완선 F 86 90 86 80 88
# 19 고현정 F 60 77 81 80 70
# 20 노사연 F 87 86 76 78 76
# 원 데이터 40행 7열
str(mytest)
# 'data.frame': 20 obs. of 7 variables:
# $ names : Factor w/ 20 levels "강감찬","계백",..: 1 16 11 10 18 7 13 17 5 12 ...
# $ gender : Factor w/ 2 levels "F","M": 2 2 1 1 1 2 2 1 2 2 ...
# $ korean : int 85 86 80 97 100 56 88 48 70 40 ...
# $ english : int 77 90 98 87 100 58 88 59 66 92 ...
# $ math : int 80 82 87 80 98 80 90 60 70 56 ...
# $ computer: int 100 93 92 85 100 92 79 50 80 40 ...
# $ science : int 96 93 90 80 94 60 87 54 73 45 ...
# names와 gender를 보존하고 나머지를 var과 val 컬럼으로 녹아 들어간다(합쳐진다)
# korean english math computer science 컬럼이 variable과 value 로 합쳐 지기 때문에
# 원 데이터가 20행 이고 5열 이었기 떄문에 20*5 100행 4열이 된다.
# 100행 4열이 된다.
meltdata <- melt(mytest, id=c("names", "gender"))
str(meltdata)
# 'data.frame': 100 obs. of 4 variables:
# $ names : Factor w/ 20 levels "강감찬","계백",..: 1 16 11 10 18 7 13 17 5 12 ...
# $ gender : Factor w/ 2 levels "F","M": 2 2 1 1 1 2 2 1 2 2 ...
# $ variable: Factor w/ 5 levels "korean","english",..: 1 1 1 1 1 1 1 1 1 1 ...
# $ value : int 85 86 80 97 100 56 88 48 70 40 ...
# names를 보존하고 english 컬럼과 math 컬럼의 Value 값만 출력하라.
newMelt <- melt(mytest, id=c("names"), measure=c("english", "math"))
str(newMelt)
# 'data.frame': 40 obs. of 3 variables:
# $ names : Factor w/ 20 levels "강감찬","계백",..: 1 16 11 10 18 7 13 17 5 12 ...
# $ variable: Factor w/ 2 levels "english","math": 1 1 1 1 1 1 1 1 1 1 ...
# $ value : int 77 90 98 87 100 58 88 59 66 92 ...
data <- read.csv("data.csv", header = T)
data
# 'data.frame': 11 obs. of 3 variables:
# $ 날짜 : Factor w/ 3 levels "01-01","01-02",..: 1 1 2 1 1 3 2 2 3 3 ...
# $ 이름 : Factor w/ 4 levels "강감찬","김완선",..: 1 3 1 3 1 3 2 4 1 3 ...
# $ 구매수량: int 3 4 2 3 2 3 6 1 5 1 ...
# formula : 행1 + 행2 ~ 열1 + 열2
# data를 행에 이름으로 그룹핑하고 열은 날짜로 나열 하는데. 구매수량 컬럼은 더하라.
widedata <- dcast(data, 이름 ~ 날짜, sum, value.var="구매수량")
widedata
# 왼쪽 -> 오른쪽으로 바뀐다.
# 날짜 이름 구매수량 # 이름 01-01 01-02 01-03
# 1 01-01 강감찬 3 # 1 강감찬 5 2 5
# 2 01-01 심수봉 4 # 2 김완선 0 6 8
# 3 01-02 강감찬 2 # 3 심수봉 7 0 4
# 4 01-01 심수봉 3 # 4 이봉원 0 1 0
# 5 01-01 강감찬 2
# 6 01-03 심수봉 3
# 7 01-02 김완선 6
# 8 01-02 이봉원 1
# 9 01-03 강감찬 5
# 10 01-03 심수봉 1
# 11 01-03 김완선 8
# 바뀐 파일 출력 저장
write.csv(widedata, "wide.csv", row.names=F)
newWide <- read.csv("wide.csv")
# 컬럼 이름 바꾸기
colnames(newWide) <- c("이름", "1월1일", "1월2일", "1월3일")
newWide
# 이름 1월1일 1월2일 1월3일
# 1 강감찬 5 2 5
# 2 김완선 0 6 8
# 3 심수봉 7 0 4
# 4 이봉원 0 1 0
long <- melt(newWide, id="이름")
colnames(long) <- c("이름", "날짜", "구매수량")
str(long)
# 'data.frame': 12 obs. of 3 variables:
# $ 이름 : Factor w/ 4 levels "강감찬","김완선",..: 1 2 3 4 1 2 3 4 1 2 ...
# $ 날짜 : Factor w/ 3 levels "1월1일","1월2일",..: 1 1 1 1 2 2 2 2 3 3 ...
# $ 구매수량: int 5 0 7 0 2 6 0 1 5 8 ...
long
# 이름 날짜 구매수량
# 1 강감찬 1월1일 5
# 2 김완선 1월1일 0
# 3 심수봉 1월1일 7
# 4 이봉원 1월1일 0
# 5 강감찬 1월2일 2
# 6 김완선 1월2일 6
# 7 심수봉 1월2일 0
# 8 이봉원 1월2일 1
# 9 강감찬 1월3일 5
# 10 김완선 1월3일 8
# 11 심수봉 1월3일 4
# 12 이봉원 1월3일 0
# students.csv 파일을 읽어서 1~2번째 컬럼만 남기고, 길게 펼쳐보세요.
stu <- read.csv("students.csv")
stu
# subject time age weight height
# 1 김철수 1 33 90 1.87
# 2 박영희 1 NA NA 1.54
# newMelt02 <- melt(stu, id=c("subject", "time"))
newMelt02 <- melt(stu, id=c(1:2))
newMelt02
# subject time variable value
# 1 김철수 1 age 33.00
# 2 박영희 1 age NA
# 3 김철수 1 weight 90.00
# 4 박영희 1 weight NA
# 5 김철수 1 height 1.87
# 6 박영희 1 height 1.54
fruits <- read.csv("fruits_10.csv")
str(fruits)
# 'data.frame': 12 obs. of 4 variables:
# $ year : int 2000 2000 2000 2000 2001 2001 2001 2001 2002 2002 ...
# $ name : Factor w/ 4 levels "apple","banana",..: 1 2 4 3 1 2 4 3 1 2 ...
# $ qty : int 6 2 7 9 10 7 3 15 13 10 ...
# $ price: int 6000 1000 3500 900 10000 3500 1500 1500 13000 5000 ...
# year만 남기고, 나머지를 아래로 길게
fruitMelt <- melt(fruits, id="year")
str(fruitMelt)
# 'data.frame': 36 obs. of 3 variables:
# $ year : int 2000 2000 2000 2000 2001 2001 2001 2001 2002 2002 ...
# $ variable: Factor w/ 3 levels "name","qty","price": 1 1 1 1 1 1 1 1 1 1 ...
# $ value : chr "apple" "banana" "peach" "berry" ...
# year와 name만 남기고 행 나열
fruitMelt <- melt(fruits, id=c(1:2))
str(fruitMelt)
# 'data.frame': 24 obs. of 4 variables:
# $ year : int 2000 2000 2000 2000 2001 2001 2001 2001 2002 2002 ...
# $ name : Factor w/ 4 levels "apple","banana",..: 1 2 4 3 1 2 4 3 1 2 ...
# $ variable: Factor w/ 2 levels "qty","price": 1 1 1 1 1 1 1 1 1 1 ...
# $ value : int 6 2 7 9 10 7 3 15 13 10 ...
# 파생 칼럼 이름을 디폴트 값으로 안하고 사용자지정으로 바꿈.
mTest <- melt(fruits, id=c(1:2), variable.name = "asdf", value.name = "qwert")
str(mTest)
# 'data.frame': 24 obs. of 4 variables:
# $ year : int 2000 2000 2000 2000 2001 2001 2001 2001 2002 2002 ...
# $ name : Factor w/ 4 levels "apple","banana",..: 1 2 4 3 1 2 4 3 1 2 ...
# $ asdf : Factor w/ 2 levels "qty","price": 1 1 1 1 1 1 1 1 1 1 ...
# $ qwert: int 6 2 7 9 10 7 3 15 13 10 ...
# melt 를 다시 반대로 분류함.
# ~ 이전 까지의 컬럼 들을 행으로 따로 분류하고 ~ 이후의 컬럼 열로 분류
dcast(mTest, year + name ~ asdf)
# year name qty price
# 1 2000 apple 6 6000
# 2 2000 banana 2 1000
# 3 2000 berry 9 900
# 4 2000 peach 7 3500
# 5 2001 apple 10 10000
# 6 2001 banana 7 3500
# 7 2001 berry 15 1500
# 8 2001 peach 3 1500
# 9 2002 apple 13 13000
# 10 2002 banana 10 5000
# 11 2002 berry 11 1100
# 12 2002 peach 5 2500
# subset 함수는 plyr 패키지가 필요하다.
library("plyr")
# subset 으로 apple 대한 행만 추출 한다.
dcast(mTest, year ~ asdf, sum, subset=.(name == "apple"))
# year qty price
# 1 2000 6 6000
# 2 2001 10 10000
# 3 2002 13 13000
# 논리 연산자 를 이용한 dcast
dcast(mTest, year ~ asdf, sum, subset=.(name=="apple" | name=="banana"))
# year qty price
# 1 2000 8 7000
# 2 2001 17 13500
# 3 2002 23 18000
# pay_data.csv 를 불러오기기, header 있음.
pay_data <- read.csv("pay_data.csv", header = T)
str(pay_data)
# 'data.frame': 24 obs. of 4 variables:
# $ user_id : Factor w/ 2 levels "김철수","박영희": 1 1 1 1 1 1 1 1 1 1 ...
# $ product_type: Factor w/ 2 levels "사과","포도": 1 1 1 1 1 1 2 2 2 2 ...
# $ pay_method : Factor w/ 3 levels "신용카드","직불카드",..: 3 2 3 2 1 1 3 2 3 2 ...
# $ price : int 1000 2000 3000 4000 6000 5000 3000 2000 4000 7000 ...
# 고객별 상품 유형에 따른구매 금액의 총합
result <- dcast(pay_data, user_id ~ product_type, sum, value.var = "price", na.rm = T)
result
# user_id 사과 포도
# 1 김철수 21000 19000
# 2 박영희 23000 20000
# 행 :고객유형, 상품유형 / 열 : 지불 방법
# ~ 전에는 행으로 나열 하고 ~ 후에는 열로 나열 하는데 price 부분은 지불 방법에 따라
# 종류가 나뉘기 때문에 지불 방법을 기준으로 price는 합쳐야 한다 그러므로 sum을쓰고 그 타겟은 price이다.
# NA 값은 거른다.
result01 <- dcast(pay_data, user_id + product_type ~ pay_method, sum, value.var = "price", na.rm = T)
result01
# user_id product_type 신용카드 직불카드 현금
# 1 김철수 사과 11000 6000 4000
# 2 김철수 포도 3000 9000 7000
# 3 박영희 사과 10000 6000 7000
# 4 박영희 포도 6000 8000 6000
# 고객 유형별 지불 방법에 따른 구매 금액의 총합
result02 <- dcast(pay_data, user_id ~ pay_method, sum, value.var = "price", na.rm = T)
result02
# user_id 신용카드 직불카드 현금
# 1 김철수 14000 15000 11000
# 2 박영희 16000 14000 13000
# 행 :고객유형, 열 : 상품유형, 지불방법
result03 <- dcast(pay_data, user_id ~ product_type+pay_method, sum, value.var = "price", na.rm = T)
result03
# user_id 사과_신용카드 사과_직불카드 사과_현금 포도_신용카드 포도_직불카드 포도_현금
# 1 김철수 11000 6000 4000 3000 9000 7000
# 2 박영희 10000 6000 7000 6000 8000 6000
Comments