IT 프로그래밍/R

r총정리

mjmjpp 2023. 11. 11. 14:21

 

#두 변수 생성(자료 입력)

speed<-c(4,7,8,9,10,11,12,13,13,14)

dist<-c(2,4,16,10,18,17,24,34,26,26)

#summary-최소,최대,평균,중앙값,1사분위수,3사분위수

summary(speed)

#mean-평균,sd-표준편차

dist(speed) #행사이의 거리

#상관계수 계산

cor(speed,dist)

#함수 plot()-두 변수의 산점도

plot(speed,dist)

plot(speed,dist)

#현재의 작업 디렉토리 확인

getwd()

#r스크립트 파일 여는거-ctrl+shift+n

 

#한명령문씩 차례로 실행-crtl+enter

#몇개의 명령문을 한꺼번에 실행-마우스로 명령문 선택후 ctrl+enter

#r script 창의 모든 명령문을 실행-ctrl+alt+r

#스크립트 파일의 저장-ctrl+s/file> save as

#저장된 스크립트 파일의 열기-file>open file/ctrl+o

#plot 창에 그려진 그래프 복사 혹은 저장-plots>save as image/sageaspdf/saveasclipboard

#패키지의 설치 및 사용-install.packages("")

#패키지의 사용 : 함수require()/library() *인용부호 없음

#패키지에대한 도움 얻기: help() 사용

help(package=MASS)

#함수(명령문) 에 대한 도움말 얻기

help(plot)

?plot

#조금 더 포괄적인 도움말 얻기-문자열plot이포함된 여러 다른 패키지에 대한 다양한 함수들에 대한 도움

help.search("plot")

??plot

##문제

기존방법<-c(78.5,60.3,81.7,69.0,64.0,62.6,86.7)

새방법<-c(82.0,74.9,88.1,62.1,78.5,79.9,94.4)

mean(기존방법)

var(기존방법)

max(기존방법)

plot(기존방법,새방법)

?xyplot

install.packages("lattice")

library(lattice)

xyplot(기존방법~새방법)

mean(기존방법,trim=0.005)

#벡터의 구성요소 알려줌 typeof()

x<-c(TRUE,FALSE,TRUE)

typeof(x)

#벡터를 구성하고 있는 요소 개수: length()

#스칼라의 생성

a<-1

#문자형데이터가 하나라도 포함되어있으면 문자형 벡터가됨

c(1,"1",TRUE)

#숫자형과 논리형이 같이 있으면 숫자형 벡터가됨

c(3,TRUE,FALSE)

#벡터의 구성요소에 이름 붙이기 - 처음 입력할때

c(seoul=9930,Busan=3497,Inchon=2944,Suwon=1194)

#이미 생성된 벡터에 이름 붙이기

pop<-c(9930,3497,2944,1194)

names(pop)<-c("Seoul","Busan","Inchon","Suwon")

pop

names(pop)

#함수 scan()에 의한 벡터 생성-scan()을 실행하면 데이터입력가능

#프롬프트에서 데이터를 직접 입력 또는 복사하고 붙여 넣기 가능

x<-scan()

#문자형 벡터 입력

y<-scan(what="character")

#외부 파일 입력

z<- scan("C:/Data/data1.txt")

#벡터에 데이터 추가 및 데이터들의 집합

x<-c(11,12,13,14)

c(x,15)#벡터에 데이터 추가

y<-c(16,17,18)

c(x,y)

#추가되는 스칼라 혹은 벡터의 위치 조절 가능

append(x,15)

append(x,15,after=2)

append(x,y)

append(x,y,after=3)

#일정한 구조를 갖는 벡터의 생성-a를 시작점으로 b를 초과하지 않을때까지

#1씩 증가하는 수열

1:5

-3:3

1.5:5.4

5:0

#함수 seq()에 의한 수열 생성

seq(from=0,to=5)

seq(from=0,to=5,by=2)

seq(from=0,to=5,length=3)

seq(from=0,by=2,length=3)

#한 숫자만 입력된 경우 1을 시작점 ,1 (증가/감소), 지정된 숫자를 끝점

seq(3)

seq(-3)

##예제 다음의 수열 생성

seq(from=2,to=11,by=3)

seq(from=9,to=45,by=9)

c(seq(from=1,to=7,by=2),seq(from=2,to=8,by=2))

#반복된 패턴이 있는 데이터 생성-함수 rep()

rep(1,times=3)

rep(1:3,times=2)

rep(c("M","F"),times=c(2,3))#m2,f 3번 반복

rep(1:3,each=2)#데이터 각 요소가 each번 반복

#each times의 활용

rep(1:3,each=2,times=2)#각 요소가 each번 반복, 전체를 times번 반복

#옵션 length의 활용

rep(1:3,length=6)#길이가 length가 될때까지 데이터전체가 반복

#옵션 each length의 활용

rep(1:3,each=2,length=8)#각 요소가 each번 반복되는 과정을 길이가 length가 될때까지 반복

#문자열을위한 함수

x<-c("Park","Lee","Kwon")

nchar(x)#문자열 x를 구성하는 문자의 개수

paste(...,sep = "")   #문자열들의 결합

substr(x,start,stop)  #문자열의 일부분 선택

toupper(x)   #영문자 대문자로 변환

tolower(x)  #영문자 소문자로 변환

strsplit(x,split)  #문자열의 분리

sub(old,new,x)  #문자열의 치환

gsub(old,new,x)  #문자열의 치환

#함수 nchar(): 문자열을 구성하고 있는 문자의 개수

x<-c("Park","Lee","Kwon")

nchar(x)

nchar("응용통계학과")

#paste():문자열의 결합

paste("모든","사람에게는","통계적","사고능력이","필요하다") #이때 디폴드 sep=" "

paste0("모든","사람에게는","통계적","사고능력이","필요하다") #이때 디폴드 sep="  "

paste("모든","사람에게는","통계적","사고능력이","필요하다",sep="-")

paste("모든","사람에게는","통계적","사고능력이","필요하다",sep="")

#입력된 숫자는 문자로 전환되어 문자열과 결합

paste("원주율은",pi,"이다다")

#문자형 벡터가 입력되면 대응되는 요소끼리 결합

#벡터의 길이가 서로 다르면 순환법칙 적용

paste("Stat",1:3,sep="")  #sep="":stat와 숫자 사이 간격 없이 결합

paste(c("Stat","Math"),1:3,sep="-")

#빈칸 없이 문자열 결합- 1.함수 paste()에 옵션=""사용 2.함수 paste0()사용

paste0("stat",1:3)

#문자형 벡터의 문자열을 하나로 결합: 옵션collapse

paste0(letters)

paste(letters,collapse = "")

paste0(LETTERS,collapse=",")

#함수 substr(): 주어진 문자열의 일부분 선택

#substr(x,start,stop)

substr("Statistics",1,4)

x<-c("응용통계학과","정보통계학과","학생회장장")

substr(x,3,6)

substr(x,c(1,3),c(2,6)) #시작점과 끝점이 벡터인 경우 필요하다면 순환법칙적용

x<-c("New York,NY","Ann Arbor,MI","Chicago,IL")

substr(x,nchar(x)-1,nchar(x))

#함수strsplit(): 문자열의 분리

#옵션 split에 지정된 기준으로 분리, 결과는 리스트

(y<-strsplit(x,split=","))

unlist(y) #함수 unlist(): 리스트를 벡터로 변환

#문자열을 구성하는 모든 문자의 분리

unlist(strsplit("PARK",split=""))

#(.)을 기준으로 문자열 분리하는 경우

#옵션 split=".": 원하는 결과를 얻을 수 없음

unlist(strsplit("a.b.c",split="."))

#옵션split="[.]" 또는 split="||."

unlist(strsplit("a.b.c",split="[.]"))

#옵션 split에는 정규표현식이 사용됨

#정규표현식에서 점(.)은 다른 의미가 있음

#함수 toupper(),tolower():()문자로 수정

x<-c("park","lee","kwon")

(y<-toupper(x))

tolower(y)

#벡터 x의 첫글자만 대문자로 변환

x

toupper(substr(x,1,1))

x

substr(x,1,1)<-toupper(substr(x,1,1))

#함수 sub(), gsub() : 문자열의 치환

#sub(old,new,문자열) : 문자열의 첫번째 old new로 치환

#gsub(old,new,문자열) : 문자열의 모든 old new로 치환

x<-"Park hates stats. He hates math,too."

sub("hat","lov",x)

gsub("hat","lov",x)

y<-paste0("banana",1:3)

sub("a","A",y)

gsub("a","A",y)

z<-"Everybody cannot do it"

sub("not","",z)

#벡터와 벡터의 연산은 대응되는 각 구성요소끼리의 연산으로 이루어짐

x<-c(7,8,9,10)

y<-c(1,2,3,4)

x+y

x-y

x*y

x/y

x^y

#벡터와 스칼라의 연산도 동일한 개념으로 실행됨

x

x+3

x/4

2^x

#벡터 연산에서 나올 수 있는 특수 문자:

Inf,-Inf: 양무한대, 음무한대

NaN:계산 불능(Not a Number)

c(-1,0,1)/0

sqrt(-1)

Inf-Inf

Inf/Inf

#벡터 연산의 순환법칙

#벡터와 벡터의 연산은 대응되는 요소끼리의 연산

#만일 두 벡터의 길이가 달라 일대일 대응이 되지 않는다면?

c(1,2,3,4,5,6)+c(1,2,3)

#길이가 짧은 c(1,2,3)을 순환 반복시켜 c(1,2,3,1,2,3)

#을 만들어 길이를 같게 만든후 연산 수행

#벡터와 스칼라의 연산도 동일하게 수행됨

#다양한 함수에서도 순환법칙이 적용됨

#긴 벡터의 길이가 짧은 벡터 길이의 배수가 되지 않는 경우

#-반복으로 두벡터의 길이를 동일하게 만들 수 없음

1:4+1:3#두 객체의 길이가 서로 배수관계에 있지 않습니다

#의도적으로 순환법칙을 사용하지 않은 경우에 위와 같은 경고

#문구를 봤다면 반드시 연산과정을 확인해야함

#대부분 잘못된 연산이 수행되었을 거임

abs(-2) #절대값 계산

sqrt(25)  #제곱근 계산

ceiling(3.475) #3.475보다 작지 않은 가장 작은 정수

floor(3.475) #3.475보다 크지 않은 가장 큰 정수

trunc(5.99) #소수점 이하 버림

round(3.475,2)  #소수 2자리로 반올림

signif(0.00347,2)  #유효수 2자리로 반올림

sin(1) #삼각함수

asin(sin(1)) #역삼각함수

log(2,base=2) #밑이 2인 로그

log(10) #자연로그

log10(10) #상용로그

exp(log(10))  #지수함수,자연로그의 역함수

x<-c(1,2,3,4,50)

mean(x)

range(x) #최소~최대 범위

IQR(x)  #Q3-Q1

sd(x)

var(x)

sum(x)

min(x)

max(x)

diff(c(1,2,3,7,11))  #뒤에있는데이터-앞에있는데이터

#결측값

#결측값기호 : NA(not availble)

#데이터에 결측값 포함여부 확인 : 함수 is.na()

x<-c(1,0,3,5,NA)

is.na(x)

sum(is.na(x)) #결측값의갯수

#NA는 자신을 포함한 어떤 대상과도 비교되지 않음

x==NA

#==비교 연산자

#NA가 포함된 데이터의 연산결과

#연산이 되지 않음

x<- c(1,0,3,5,NA)

meax(x)

max(x)

#연산에서 NA를 제거하는 방법-옵션 na.rm=TRUE

mean(x,na.rm=TRUE)

max(x,na.rm=TRUE)

#벡터 단위로 각 대응되는 요소끼리의 비교가 이루어짐

x<-c(3,8,2)

y<-c(5,4,2)

x>y

x>=y

x<y

x<=y

x==y

x!=y

x<-1:3

x>2

x<2

x<=2|x>=3

x<=2&x>=1

#각 요소끼리의 비교결과보다는 벡터 전체의 비교결과를 원하는 경우

#any(),all()

x<-1:5

any(x>=4)

all(x>=4)

#벡터의 구성 요소 중 특정 조건을 만족하는 요소의 개수 혹은 비율

x>=4

sum(x>=4)

mean(x>=4)

#논리형벡터를 숫자형 함수에 적용하면 숫자형 벡터로 전환됨

#연산자 %in%:벡터의 구성요소중 특정한값 포함 여부 확인

x<-1:5

x%in%c(2,4)

#벡터 x의 구성요소 중 하나하나와 %in% 오른쪽에 주어진 값 비교

#x==c(2,4)는 어떤 작업을 수행하는가?

#순환반복 작용, c(2,4,2,4)와 같은 기능

x<-1:5

x==c(2,4)

#두 객체의 길이가 배수관계에 있지 않음 적용 안됨

#벡터의 인덱싱-벡터의 일부분을 선택하는 작업

#x[a]의 형태 : 벡터 a는 정수형, 논리형, 문자형(구성요소에 이름이 있는 경우)

#정수형벡터에 의한 인덱싱

#모두 양수 : 지정된 위치의 자료 선택

#모두 음수 : 지정된 위치의 자료 제외

y<-c(2,4,6,8,10)

y[c(1,3,5)]

y[c(-2,-4)]

y[c(2,2,2)] #같은 위치 반복 지정 가능

y[6] #지정한 위치가 벡터 길이보다 큰 경우

#문자형 벡터에 의한 인덱싱

#벡터의 구성요소에 이름이 있는 경우에만 적용가능

pop=c(Seoul=9930, Busan=3497, Inchon=2944, Suwon=1194)

pop

pop[c("Seoul","Suwon")]

#논리형 벡터에 의한 인덱싱

#- TRUE가 있는 위치의 자료만 선택

#- 벡터의 비교에 의한 자료 선택에서 유용하게 사용됨

y

y[c(TRUE,TRUE,FALSE,FALSE,TRUE)]

y>3

y[y>3]

#조건에 의한 인덱싱

#-벡터x의 개별 값 중 평균값보다 큰 값 선택

x<-c(80,88,90,93,95,94,99,78,101)

x>=mean(x)

x[x>=mean(x)]

#예제)벡터 x에서 1)평균으로부터 +-1 표준편차 안에 있는 관찰값

#2)평균으로부터 +-1표준편차와 +-2표준편차 사이에 있는 관찰값

#3)평균으로부터 +-2 표준 편차를 벗어나는 관찰값

z<-(x-mean(x))/sd(x)

x[abs(z)<=1]

x[abs(z)>1&abs(z)<=2]

x[abs(z)>2]#데이터 없음이라고 뜸

#요인(Factor)

#범주형 데이터만을 위한 구조

#-벡터와 같은 1차원 배열,

-수준(level): 요인이 취할 수 있는 값

#명목형 요인의 생성: 함수 factor()

gender<-c("Male","Female","Female")

gender_f<-factor(gender)

gender

gender_f

#요인 gender_f의 개별 자료: 인용부호 없음

#Female이 첫 번째, Male이 두번째 level.알파벳 순으로 결정

#수준(Levels): 요인 변수에 정의된 값들

#요인과 문자형변수의 차이

as.numeric(gender)

as.numeric(gender_f)

as.numeric(gender_f)+1

gender_f+1#직접적인 수리적계산이 불가능

#요인은 수준이름으로 표시되지만 내부적으로 알파벳 순서에 따라 정수값으로 저장된다

#요인은 as.numeric()함수를 통해 숫자화 할 수 있다.

#이 기능을 이용하여 요인은 다양한 계량적 분석이 가능해진다.

#문자는 문자열로 표시, 저장되어 계량분석이 제한적이다.

#옵션 labels의 활용

#수준의 이름 변경

x<-c(1,3,2,2,1,4)

factor(x)

factor(x,labels=c("A","B","C","D"))

#수준 병합

factor(x,labels=c("A","A","B","B"))

x

#요인의 유형 및 속성

#정수형.Female=1,Male=2로 입력되어있음

#class속성: 객체의 속성중 하나

#-요인

#-객체 지향 프로그램에서 중요한 역할

gender<-c("Male","Female","Female")

typeof(gender_f) #데이터 유형 표시

class(gender_f)

gender_f<-factor(gender)

gender_f

typeof(gender_f) #데이터 유형표시

class(gender_f) #class속성 표시

summary(gender) #문자형:속성분석

summary(gender_f) #요인형:빈도분석

#순서형 요인의 생성 : 순서형은 table, bar, chart, 모델링 등에서 효과적

#-함수 factor()에 옵션 order=TRUE추가

#-level의 순서를 조절하고자 하는 경우 옵션 level에서 지정

#결과적으로 storage에 배정되는 숫자 변경

income<-c("Low","Medium","High","Medium")

factor(income)

as.numeric(factor(income))

factor(income,order=TRUE) #High 1,Low2, Medium3 배정

as.numeric(factor(income,order=T))

factor(income,order=TRUE,level=c("Low","Medium","High"))

as.numeric(factor(income,order=TRUE,level=c("Low","Medium","High")))#low 1,medium 2, high3 배정

#숫자형 벡터를 요인으로 변환

#연속형 변수-> 범주형 변수로 전환

#-변환방법1: 논리형 벡터 이용

#-변환방법2: 함수 cut()이용

x<-c(80,88,90,93,95,94,100,78,65)

cat.x<-cut(x,breaks=c(0,80,90,100),include.lowest = TRUE,

           right=FALSE,labels=c("C","B","A"))

cat.x

#breaks:구간의 최솟값,최댓값을 포함한 구간 설정벡터

#right:구간이 (a<x<=b)이면 TRUE,(a<=x<b)이면 FALSE

#include.lowest : 구간의 최소값(right=TRUE일때)또는 최대값(right=FALSE일때)과 같은 관찰값도 변환에 포함시킬지 여부

#labels: 수준의 라벨 지정

#함수 cut()으로 순서형 요인 생성: 옵션 ordered_result=TRUE

cut(x,breaks=c(0,80,90,100),include.lowest = TRUE,right = FALSE,labels=c("C","B","A"),ordered_result = TRUE)

#날짜

#시간의 흐름에 따라 데이터 얻는 경우,중요한 변수

#생성: 문자형벡터에 함수 as.Date()적용

#문자형 벡터의 디폴트 형태:yyyy-mm-dd

x<-as.Date(c("2017-01-01","2018-01-01"))

x

#유형:숫자형. 1970 11일부터 날수

typeof(x)

x[2]-x[1]

#일정한 간격의 날짜 생성:함수 seq()

#-동일한 간격의 날짜 생성: 옵션 by에 숫자 지정

s1<-as.Date("2018-03-01")

e1<-as.Date("2018-03-31")

seq(from=s1,to=e1,by=7)

#증가 폭을 주 단위 혹은 월 단위로 조정가능

seq(from=s1,by="week",length=5)

seq(from=s1,by="month",length=5)

seq(from=s1,by="year",length=7)

#행렬과 배열의 기본 특성

#행렬의 생성1 : matrix

#-행과 열의 개수 nrow=또는 ncol=로지정(둘중하나)

x<-matrix(1:12,nrow = 3) #자료가 열단위로 입력

x

y<-matrix(1:12,nrow=3,byrow=TRUE) #옵션 byrow=TRUE로 행 단위로 입력

y

#행렬 생성2: cbind(),rbind()

#-cbind(): 벡터들을 열단위로 묶어 행렬 생성

#-rbind():벡터들을 행단위로 묶어 행렬 생성

x1<-1:3

x2<-4:6

(A<- cbind(x1,x2))

B<-rbind(x1,x2)

B

#기존의 행렬에 행 또는 열 추가

cbind(A,X3=7:9) #기존의 행렬에 열 추가

rbind(A,7:8)

#결합대상이되는 벡터의 길이가 다른 경우: 순환법칙 적용

X1<-1:4

X2<-5:6

X3<-7

cbind(X1,X2,X3)

#행렬의 생성3: dim()

x<-1:12

dim(x)<-c(3,4)

x

#행렬의 행과 열에 이름 붙이기

#함수 rownames() colnames()

x

rownames(x)<-c("one","two","three")

colnames(x)<-c("a","b","c","d")

x

#행렬의 길이 확인

x

length(x)

nrow(x) #행의 개수 제시

ncol(x) #열의 개수 제시

dim(x) #, 열 제시

#배열의 생성

#함수 array() :각 차원에 대한 정의를 함수 c()로 지정

xyz<-array(1:24,c(4,3,2)) #,,구역 결정

xyz

#배열의 각 차원에 이름 부여

#함수 dimnames():리스트로 할당

dimnames(xyz)<- list(x=c("x1","x2","x3","x4"),

                     y=c("y1","y2","y3"),

                     z=c("z1","z2"))

xyz                    

#행렬과배열의 인덱싱

#행렬인덱싱

#x[i,j]:행렬 x i번째 행,j번째 열의 요소

#x[i,]:행렬 x i번째 행 전체

#x[,j]:행렬 x j번째 열 전체

x

x[2,3]

x[1,]

x[,2]

x[1:2,]

 

#배열 인덱싱

#-차원수만큼의 첨자 필요

xyz<-array(1:24,c(4,3,2))

xyz[,1,1]#,,차원

xyz[,,1]

xyz[1,1,1]

xyz[2,,]

xyz

 

#행렬의 연산

#선형대수 문제뿐만 아니라 다양한 통계분석에서도 종종 사용됨

A<-matrix(1:4, nrow=2, byrow=T)

B<-matrix(5:8, nrow=2, byrow=T)

A<-matrix(1:4, nrow=2, byrow=T)

B<-matrix(5:8, nrow=2, byrow=T)

A

B

A*B#행렬을 구성하는 숫자 각각에 적용

A%*%B#행렬 A B곱하기

colMeans(A) #행렬 A 각 열의 평균값으로 구성된 벡터

??colSums(A) #행렬 A 각 열의 합으로 구성된 벡터

t(A) #행렬 A의 전치

rowSums(A) #행렬 A 각 행의 합으로 구성된 벡터

diag(A) #행렬A의 대각선 원소로 구성된 벡터

x<-c(10,20);diag(x) #벡터 x를 대각선 원소로 하는 대각행렬

??diag(2)

A

solve(A) #행렬A의 역행렬

solve(A)%*%A #A의 역행렬과 A의 곱

b<-c(5,6);solve(A,b) #행렬 Ax=b의 해

#x+2y=5//3x+4y=6

#데이터 프레임의 생성:data.frame()

df1<-data.frame(x=c(2,4,6),y=c("a","b","c"))

df1

#벡터 x y df1의 변수

#행 번호 자동 생성

#함수 str(): 데이터 객체의 구조 확인

str(df1)

#함수 data.frame()의 특성

#입력되는 벡터의 길이가 같아야함

data.frame(x=c(2,4),y=c("a","b","c"))

#길이가 1인 벡터: 순환법칙 적용

data.frame(x=1,y=c("a","b","c"))

#데이터 프레임의 행과 열 이름, 변수 개수 확인

#-(변수)이름: 함수colnames(),names()

#-행이름: 함수 rownames()

#-변수개수:length()

df1

colnames(df1) #열이름

names(df1) #열이름

rownames(df1) #행이름

length(df1) #변수개수

#데이터 프레임의 인덱싱1: 리스트에 적용되는 방식

#-(변수)선택

#df[[a]] 또는 df[a]의 형식: 벡터 a는 숫자형 혹은 문자형

#df[[a]]:한변수의 선택.결과는 벡터

#df[a]:하나 또는 그이상의 변수 선택.결과는 데이터 프레임

df1

typeof(df1)

df1[1] #결과가 데이터 프레임-세로로 나열

df1[[1]] #결과가 벡터-가로로 나열

df1["x"]

df1[["x"]]

#데이터 프레임의 변수선택

#-벡터 형태로 선택하는 것이 일반적

#-df[[a]]의 형태가 더 많이 사용됨

#조금 더 편한 방법: $기호 사용

df1[["x"]]

df1$x

#데이터 프레임의 인덱싱2: 행렬에 적용되는 방법

#-df[i,j]의 형태

#-선택된 변수가 하나이면 결과는 벡터 하나이상이면 결과는데이터 프레임

df1[c(1,2),1] #앞에가 행, 뒤에가 열

df1[c(1,2),]

#함수 with

#데이터 프레임을 대상으로 하는 통계분석

#-데이터 프레임의 개별 변수를 벡터 형태로 선택하여 분석 진행

#-인덱싱 기법에 의한 변수 선택:매우 번거로운 방법

#함수 with():편하게 데이터 프레임에 접근하는 방법

#-일반적인 사용 형태: with(데이터 프레임, R명령문)

#-with()안에서는 지정된 데이터 프레임의 변수를 인덱싱 없이 사용 가능

#예제: 데이터 프레임 airquality

#-미국 뉴욕시의 공기 질과 관련된 데이터

#-변수 Temp의 표준화: (x-~x)/s

seq(-3)

c(seq(from=1,to=7,by=2),seq(from=2,to=8,by=2))

rep(1:3,each=2,times=2)

rep(1:3,each=2,length=8)

z.Temp<-(Temp-mean(Temp)/sd(Temp))

z.Temp<-(airquality$Temp-mean(airquality$Temp))/sd(airquality$Temp)

z.Temp<-with(airquality,(Temp-mean(Temp))/sd(Temp))

#tibble:tidyverse에 속한 패키지들이 공통적으로 사용하는 데이터 프레임

install.packages("tidyverse")

library(tidyverse)

#1.기존의 데이터 프레임을 tibble로 변환

as_tibble(cars)

#2.개별 벡터를 이용한 tibble의 생성

tibble(x=1:3,y=x+1,z=1)

#길이가 1인 스칼라만 순환법칙 적용

#함께 입력되는 변수를 이용한 다른 변수의 생성가능

#(변수) 단위로 입력

data.frame(x=1:3,y=x+1)

#3.행단위로 입력하여 tibble생성

tribble(

  ~x,~y,

  1,"a",

  2,"b",

3,"c")

#첫줄 :변수이름은 ~로 시작/각자료는 콤마로 구분

 

#tibble과 전통적 데이터 프레임의 비교

#1.데이터 프레임의 출력 방식

#2.인덱싱 방법

#3.Row names를 다루는 방식

 

#1. 출력 방식의 차이 : 가능한 모든 자료를 출력, 대규모의 경우 내용 확인 어려움

data(Cars93,package="MASS")

Cars93

#Tibble; 처음 10개 케이스만 출력, 한 화면에서 자료의 특성 파악 용이

as_tibble(Cars93)

#2.Row names 처리 방식의 차이

#전통적 데이터 프레임: 자료 출력시 row name함께 출력

#Tibble: 생략

head(mtcars)

mtcars_t<-as_tibble(mtcars)

print(mtcars_t,n=6)

#3.생략된 row name:변수로 변환

#-함수 rownames_to_column()

mtcars_d<-rownames_to_column(mtcars,var="rowname")

mtcars_t<-as_tibble(mtcars_d)

mtcars_t

#인덱싱방법의 차이

#-기호'$'를 이용하는 경우: 변수이름의 부분 매칭 허용 여부

#전통적 데이터 프레임: 부분매칭 허용

df1<-data.frame(xyz=1:3,abc=letters[1:3])

df1$x

#tibble :부분매칭 불허

tb1<-as_tibble(df1)

tb1$xyz

#행렬방식의 인덱싱 결과

#전통적인 데이터 프레임 : 선택되는 변수의 개수에 따라 벡터 혹은 데이터 프레임

#tibble : 선택되는 변수의 개수와 관계없이 항상 tibble유지

mtcars[,1:2] # 변수 빼고

mtcars

mtcars[,1]

 

mtcars_t[,1:2] #변수 포함, tibble 씌운거

mtcars_t[,1]

mtcars_t[1,1]

 

#리스트

#구조의 특성

#-가장 포괄적인 구조

#-구성요소: 벡터,배열,데이터프레임,함수,다른 리스트

#-서로 다른 유형의 객체를 한데 묶은 또 다른객체

#리스트 생성 : list()

x<-list(a=c("one","two","three"),b=1:3,C=list(-1,-5),

        d=data.frame(x1=c("s1","s2"),x2=1:2)) #열을 기준으로 생김

x       

#리스트의 인덱싱

#list[[a]]또는 list[a]의 형태

#-list[a]:결과는 리스트

#-list[[a]]또는 list$a : 해당되는 구성요소의객체구조

x[1] #원래의 구조가 그대로 유지되어 항상 리스트가됨

x[[1]] #해당되는 구성요소의 객체 구조가됨,문자형 벡터가 됨

str(x[[1]])

x[[4]] #리스트 x 4번째 요소를 데이터 프레임 형태로 선택

x[[4]][[2]]  #리스트x 4번쨰 요소의 두번째 열을 벡터 형태로 선택

x$d$x2

x[[4]][2]  #리스트 x 4번째 요소의 두번째 열을 데이터 프레임형태로 선택

 

#데이터의 입력

#1.Base R함수로 가능: read.table(),readcsv()..-시간소요, 비효율적

#2.텍스트파일불러오기: 패키지readr

#-read_table2(), read_csv(), read_fwf()

#3.Excel파일불러오기 : 패키지readxl

#-read_excel()

#4.HTML테이블불러오기 : 패키지rvest

#-read_html(),html_nodes(),html_table()

#텍스트파일불러오기:패키지readr

#행과 열의 2차원 텍스트파일불러오기

#자료의 입력형태에 따라 다른 함수 사용

#-빈칸구분:read.table(),read_table2()/콤마 구분:read_csv()/고정포멧:read_fwf()

#앱서버 텍스트파일불러오기 가능

#압축파일은 자동으로 압축해제하고 불러옴

 

#함수read_table2()로 텍스트 파일 불러오기

#-read_table():자료 사이의 간격이 일정한 경우에 사용가능

#-read_table2(): 자료 사이의 간격에 제약 없음

#1) 데이터 파일 첫줄에 변수이름이 입력되어 있는 경우-파일 위치와 함께 파일이름만 입력

library(readr)

install.packages("readr")

getwd()

read_table2("C:/pmj/R.txt")

#사용자가 변수 유형선언

#-col_types에 유형을 나타내는 문자 입력된 변수 순서대로 나열

#-자료 유형을 나타내는 문자: c(문자형),i(정수형),d(실수형),n(숫자형),I(논리형),f(요인),D(날짜)

read_table2("C:/pmj/R.txt",col_types="dcd")

#2)변수이름없이 데이터만입력되어 있는 경우

#-col_names 반드시 사용

#-FALSE지정:변수이름은X1,X2,...

#-변수이름이 있는 문자형 벡터 지정

read_table2("C:/pmj/변수없음.txt",col_names=FALSE)

read_table2("C:/pmj/변수없음.txt",col_names=c("age","gender","income"))

#3)데이터 파일에 주석이 입력된 경우

#-commment:주석기호 지정

read_table("C:/pmj/주석기호.txt",comment="#")

read_table("C:/pmj/주석기호.txt",skip=3)

#4)결측값이 NA가 아닌 다른 기호로 입력된 경우

#-NA에 해당 기호 지정

#-(.)으로만 결측값 입력:na="."

read_table("C:/pmj/결측값.txt",na=".")

#(.) NA가 모두 결측값으로 입력:na=c(“.”,”NA”)

read_table("C:/pmj/결측값.txt",na=c(".","NA"))

#함수 read_csv() CSV파일 불러오기

#-CSV파일:자료들이 콤마로 구분된 텍스트 파일

read_csv("C:/pmj/csv파일불러오기.txt")

#변수이름 규칙: 문자로 시작하고 중간에 빈칸이 없어야함

#변수이름(var 1) backtick기호(tab키 위, 인용부호와 구분)

#:규칙에 어긋난 문자열을 tibble에서 변수이름으로 사용할때 적용

#read_table2()에서 사용했던 입력 요소

#-cor_types,col_names,na,comment,skip:동일하게 작동

read_csv("C:/pmj/csv파일불러오기.txt",

         col_names = FALSE,

         comment="#",na=c(".","NA"))

read_csv("C:/pmj/csv파일불러오기.txt",

         col_names = FALSE,

         col_types="dcd",comment="#",na=c(".","NA"))

#함수 read_fwf()로 고정 포맷파일 불러오기

#-고정 포맷파일

#고정포맷파일.txt age1-2, gender3, income 4-7

#read_table(),read_csv는 이용할 수 없는 형태

read_fwf("C:/pmj/고정포맷파일.txt",

         col_positions=fwf_widths(widths = c(2,1,4),

                                  col_names=c("age","gender","income"))

)

read_fwf("C:/pmj/고정포맷파일.txt",

         col_positions=fwf_positions(start = c(1,3,4),

                                     end=c(2,3,7),

                                  col_names=c("age","gender","income"))

)

#데이터프레임을 외부 텍스트 파일로 저장

#write_delim():빈칸(디폴트)로 구분된 자료로 저장

#write_csv():콤마로 구분된 자료로 저장

#write_tsc():탭으로 구분된 자료로 저장

t<-data.frame(height=c(68,59,60,61),

           weight=c(115,115,117,119))

t

write_delim(women,"c:/pmj/women.txt")

write_csv(women,"c:/pmj/women.csv")

write_tsv(women,"c:/pmj/women.tsv")

#Excel 파일 불러오기

#패키지 xlsx의 함수 read.xlsx()

#패키지 readxl의 함수 read_excel()

#excel파일을 csv파일로 전환하여 불러오기

#패키지readxl의 함수read_excel()

install.packages("readxl")

library(readxl)

read_excel("C:/pmj/Rexcel.xlsx")

#옵션range:시트 전체 데이터중 일부분만 입력

read_excel("C:/pmj/Rexcel.xlsx",range="A1:B2")

#SAS파일 불러오기(skip)

#SAS-범용 통계 소프트웨어.수많은 사용자 보유

#sas전용 데이터 파일의 입력 방법: 패키지 haven의 함수 read_sas()

library(haven)

read_sas("D:/Data/data6.sas7bdat")

#HTML의 테이블 불러오기

#-웹에 있는 엄청난 양의 데이터

#HTML테이블-패키지rvest/함수 read_html(),html_nodes(),html_table()

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<기말고사 범위 정리>

#기본 dplyr함수

-행을 작업 대상으로 하는 함수

-열을 작업 대상으로 하는 함수

-요약통계량 계산 함수

#그룹 데이터 프레임

-그룹데이터 프레임 생성, 그룹데이터 프레임에서 기본 dplyr 함수의 작동 방식

#여러 열을 대상으로 동일한 작업 수행

#행단위 작업 수행

 

#행을 작업 대상으로 하는 함수-filter(), slice(), arrange(),distinct()

#열의 작업 대상으로 하는 함수- select(), rename(), rename_with(), mutate(),transmutate(),relocate()

#요약 통계량 계산 함수- summarise()

#기본 dplyr함수들의 공통점

- 첫번째 입력 요소는 데이터 프레임 또는 (tibble)

- 각 함수 내에서는 인덱싱 없이 데이터 프레임의 변수 사용 가능

- 각 함수의 결과물은 데이터 프레임(또는 tibble)

pipe 기능으로 더 효율적인 프로그램 작성 가능

 

#pipe기능

#-명령문을 서로 연결하여 한 명령문의 결과물을 다음 명령문의 입력 요소로 직접 사용할 수 있도록 하는 기능

#pipe 연산자 : %>% (단축키: shift+ctrl+m)

#기본적인 형태:-lhs %>% rhs: lhs(데이터 객체 또는 데이터 객체를 생성하는 함수),rhs(lhs를 입력 요소로 하는 함수)

#

x %>% f()->f(x)

x %>% f(y)->f(x,y):첫번째 요소

x %>% f(y,.):첫번째 요소가 아닌 경우 해당 위치에"." 표시

 

 

install.packages("dplyr")

library(dplyr)

x<-1:5

y<-log(x)

y

mean(x)

x %>% mean()

plot(x,y)

x %>% plot(y)

y %>% plot(x,.)

mean(log(x))

x %>% log() %>% mean()

sqrt(mean(log(x)))

x %>% log() %>% mean() %>% sqrt()

#pipe, 할당문

x=1:5

u=x %>% mean

u

v<-x %>% mean

v

x %>% mean->w

w

s=as_tibble(airquality) %>% print(n=3)# 3개만 출력

dim(s)

#행을 작업 대상으로 하는 함수

#조건에 의한 행 선택 : filter()

#조건을 모두 만족하는 행 선택, 조건 설정에 사용되는 연산자(비교 연산자, 논리 연산자,%in%연산자)

library(tidyverse)

mtcars_t<- as_tibble(mtcars)

mtcars_t %>% filter(mpg>=30)

mtcars_t %>% filter(mpg>=30,wt<1.8)#mpg의 값이 30 이상이고 wt의 값이 1.8 미만

mtcars_t %>% filter(mpg<=30,cyl%in%c(6,8),am==1)#변수 mpg 30 이하, 변수 cyl 6또는 8, 변수 am 1(manual)인 자동차 선택

mtcars_t %>% filter(

  mpg>= median(mpg),mpg<=quantile(mpg,probs=0.75)

                    ) %>% print(n=3) #변수 mpg의 갓이 mpg의 중앙값과 q3사이에 있는 자동차 선택

# 벡터 x가 특정 두 숫자 (left,right)사이에 있는지 확인

#1)x>=left&x<=right 2)between(x,left,right)

#예제:airquality:

library(dplyr)

airs<-as_tibble(airquality) %>% print(n=3)

airs %>% filter(is.na(Ozone)|is.na(Solar.R)) %>% print(n=3)# 변수 ozone또는 solar.R이 결측값인 관찰값 선택

#위치에 의한 행선택: slice() 및 그와 관련된 함수

#함수 slice()에 의한 행 선택

#-행번호를 직접 입력하여 특정 행의 선택 또는 제거

#-선택: 양의 정수

#-선택: 음의 정수

iris_t<-as_tibble(iris)

iris_t %>% slice(5:10)#iris tibble로 전환하고 5~10번째 행선택

iris_t %>% slice(-(5:10)) %>% print(n=3)#5~10번째 행 제거

#마지막행 선택

iris_t %>% slice(n())

#*함수 n()-데이터 프레임의 행개수를 세는 함수/단독으로는 사용할 수 없음

#함수 slice_head() slice_tail()에 의한 행 선택

#-처음 몇 개 행 또는 마지막 몇 개 행 선택

#-행의 개수(n) 또는 비율(prop) 지정

#iris의 처음 3개 행 선택

iris_t %>% slice_head(n=3)

#iris의 마지막 3개 행 선택

iris_t %>% slice_tail(n=3)

#함수 slice_sample()에 의한 행 선택

#-단순임의추출에 의한 행 선택

#-행의개수(n) 또는 비율(prop) 지정

#-비복원추출이 디폴트.replace=TRUE 지정으로 복원 추출 가능

#iris에서 3개 행 임의 추출

iris_t %>% slice_sample(n=3)

#전체 행 중 2% 행 복원 추출

iris_t %>% slice_sample(prop=0.02,replace=TRUE)

#함수 slice_max() slice_min()에 의한 행 선택

#-특정 변수가 가장 큰 값 또는 가장 작은 값을 갖는 행 선택

#-기준 변수와 선택하고자 하는 행의개수 (n)또는 비율(prop)지정

#iris에서 Sepal.Width의 값이 가장 큰 2개 행 선택

iris_t %>% slice_max(Sepal.Width,n=2)

#iris에서 Peta.Length의 값이 가장 작은 2개 행 선택

iris_t %>% slice_min(Petal.Length,n=2)

#행의 정렬:arrange()

#특정 변수를 기준으로 데이터 프레임의 행 재배열

#기본적인 사용법: arrange(df,var_1,var_2,...)

#-df: 데이터 프레임, var_1: 1정렬 기준 변수, var_2: 2정렬 기준 변수

#2개 이상의 정렬 기준 변수 나열: 추가된 변수는 앞선 변수가 같은 값을 갖는 행의 정렬기준

#오름 차순 정렬이 디폴트

#내림차순 정렬: 기준 변수를 함수 desc()에 입력

#변수 mpg의 값이 가장 좋지 않은 자동차부터 재 배열

mtcars_t %>% arrange(mpg) %>% print(n=3)

#mpg가 가장 좋지 않은 자동차부터 배열하되, mpg 값이 같은 자동차는 wt의 값이 높은 자동차부터 배열

mtcars_t %>% arrange(mpg, desc(wt)) %>% print(n=3)

#51일부터 5 10일까지의 자료만을 대상으로 변수ozone의 값이 가장 낮았던 날부터 재배열

airs_1<-as_tibble(airquality) %>% filter(Month==5,Day<=10)

airs_1 %>% arrange(Ozone)

#airs_1을 변수 Ozone이 결측값인 케이스를 가장 앞으로 배열

airs_1 %>% arrange(!is.na(Ozone))

#배열 기준으로는 논리형 벡터 사용/TRUE,FALSE배열에서 우선 순위는 FALSE/!is.na(Ozone): 변수 Ozone이결측값인 케이스가 우선 순위

#airs_1을 변수 Ozone이 가장 높은 날부터 배열하되 결측값이 있는 케이스를 가장 앞으로 배치

airs_1 %>%  arrange(!is.na(Ozone),desc(Ozone))

#중복된 행 제거:distinct()

#-중복 여부를 결정할 변수 지정: 없는 경우에는 모든 변수 대상

#-옵션.keep_all= TRUE: 모든 변수 유지. 중복된 행 중 첫번째 행만 유지/=FALSE:해당 변수만

df1<-tibble(id=rep(1:3,times=2:4),x1=c(1:2,1:3,1:4))

df1

#-변수 id가 중복되지 않는 행 선택

df1 %>% distinct(id,.keep_all = TRUE)

#변수 id가 중복된 행 중 x1의 값이 가장 큰 행 선택

df1 %>% arrange(id,desc(x1)) %>% distinct(id,.keep_all = TRUE)

#모든 변수의 값이 중복된 행 제거

df2<-tibble(id=rep(1:3,each=2),x1=c(2,2,3,1,4,4))

df2

df2 %>% distinct(.keep_all=TRUE)

#열을 작업 대상으로 하는 함수
#
열을 선택: select()
#-
데이터 세트의 크기 증가: 지나치게 많은 변수를 줄이는 작업 필요
#-
분석에 필요한 변수 선택 필요
#-
변수선택방법: 패키지 tidyselect의 방식 적용
#-<tidy-select>
방식
#1)
열 번호(또는 열이름)에 의한 선택
#2)
변수의 유형에 위한 선택
#3)
변수 선택과 관련된 몇몇함수에 의한 선택
#1)
열 번호(또는 열이름)에 의한 선택
#-
열이름은 열번호와 같은 취급/열번호를 콤마로 구분하여 나열/연속된 열은 콜론(:)연산자를 이용하여 나열/나열된 열들은 차례로 합집합 구성
#
예제:mtcars
#-
행이름을 변수  row.name으로 추가하고  tibble  전환
#-
첫번째에서 세번째 그리고 일곱번째 변수 선택
install.packages("tidyselect")
library(tidyselect)
mtcars_t<-mtcars %>%
  rownames_to_column(var="row.name") %>%
  as_tibble()
mtcars
rownames 

mtcars_t %>% select(1:3,7)

#이렇게 해도됨!

mtcars_t %>% select(row.name:cyl,wt)

#열을 제거하고자 하는 경우에는 논리 부정 연산자 또는 마이너스 연산자를 사용해야함

#열제거- 논리 부정 연산자(!): 여집합 구성

mtcars_t %>%select(!c(1:3,7))

#열제거- 마이너스 연산자(-): 차집합 구성

mtcars_t %>% select(1:3,-1)#(1,2,3)에서 1을 제외함

mtcars_t %>% select(1:3,!1)#(1,2,3) (1을 제외한 나머지)의 합집합-> 전체

#마이너스 연산자를 첫번째로 입력: 논리 부정 연산자와 동일

mtcars_t %>% select(-c(1:3,7))

#2)변수 유형에 의한 선택

#함수 where()에 의한 선택

#사용법:where(fn)

#fn: 결과가 TRUE가 또는 FALSE predicate 함수

#) is.numeric,is.character

#-fn의 결과가 TRUE인 변수 선택

install.packages("ggplot2")

library(ggplot2)

mpg %>% print(n=3)

mpg %>% select(where(is.numeric))#데이터 프레임에서 숫자형 변수만 선택

#문자형 변수나 숫자형 변수의 선택

mpg %>% select(where(is.numeric)|where(is.character))#변수 유형을 함께 고려 해야하는 경우에 논리 연산자 & |를 사용하게 댐

 

#3)변수 선택과 관련된 함수

#everything():모든 변수 선택

#last_col(): 마지막 변수 선택

#starts_with("x"):이름이 "x"로 시작하는 변수 선택

#ends_with("x"):이름이 "x"로 끝나는 변수 선택

#contains("x"):이름에 "x"가 있는 변수 선택

#num_range("x",1:10):x1,x2,...,x10과 동일

#all_of(vec):벡터 vec에 이름 있는 변수 선택. , 데이터 프레임에 없는 변수 이름이 vec에 있으면 오류 발생

#any_of(vec):all_of(vec)과 동일. 단 데이터 프레임에 없는 이름이 vec에 있어도 오류 발생하지 않음

 

#mtcars_t에서 첫번째와 마지막 변수 선택

mtcars_t %>% select(1,last_col())

#mtcars_t에서 이름이 "m"으로 시작하는 변수 선택

mtcars_t %>% select(starts_with("m"))

#이름이 "p"로 끝나는 변수

mtcars_t %>% select(ends_with("p"))

#이름에 "A"가 있는 변수 선택

mtcars_t %>% select(contains("A"))#이 경우는 ingnore.case=TRUE가 디폴트로 포함되어 대문자와 소문자를 구분하지 않는 것

mtcars_t %>% select(contains("A",ignore.case = FALSE))#ignore.case=FALSE로 설정하여 대문자만 포함하도록 함

#벡터에 이름이 있는 변수 선택

#데이터 프레임을 설정하고 그 데이터 프레임안의 변수가 존재하는지를 확인한다

vars<-c("model","mpg","wt")

mtcars_t

mtcars_t %>% select(any_of(vars))

mtcars_t %>% select(all_of(vars))

#숫자형 변수 중 이름에 "c"가 있는 변수 선택

mtcars_t %>% select(where(is.numeric)&contains("c"))

#열 이름 변경 : select(), rename(), rename_with()

#select()에 의한 열 이름 변경

#-new_name=old_name 방식

#-변경되지 않은 열 삭제(select는 기본적으로 변수 선택함수)

mtcars_t<-mtcars %>%

  rownames_to_column(var="row.name") %>%

  as_tibble()

#변수 row.name model로 이름 변경,이때 바뀐 변수만 드러남

mtcars_t %>% select(model=row.name)

#변수이름을 바꾸고 모든 열 유지

mtcars_t %>% select(model=row.name,everything())

#rename()에 의한 변경

#-new_name=old_name방식

#-모든 열 유지

mtcars_t %>% rename(model=row.name)

#rename_with()에 의한 변경

#-많은 변수 이름을 공통된 양식으로 모두 변경해야 하는 경우

#) 대문자 이름을 모두 소문자로 변경

#사용법: rename_with(fn)/fn:변수이름을 변경하는 함수

#mtcars_t의 모든 변수 이름 대문자로 변경

mtcars_t %>% rename_with(toupper)#모든 변수가 변경대상이 되는 것이 디폴트

#이름에 "a"가 포함된 변수 이름 대문자로 변경

#rename_with()의 대상은 모든 변수가 디폴트

#함수의 입력요소로 변경 대상

mtcars_t %>% rename_with(toupper,contains("a"))

#열의 위치 변경:relocate()

#-여러 개의 열 위치 변경 가능

#-<tidy-select>방식으로 열 선택

#-이동위치: 제일 앞 (디폴트) 옵션.after혹은 .before에서 지정 가능

#iris Species를 첫번째 변수로 이동

iris_t<-as_tibble(iris)

iris_t

iris_t %>% relocate(Species)#species를 첫번째 변수로 이동

iris_t %>% relocate(ends_with("th"),.after = Species)

iris_t %>% relocate(ends_with("th"),.after=last_col())

 

#새로운 열의 추가 :mutate() transmute()

#-기존의 변수를 이용하여 새로운 변수 생성

#-mutate(): 대상 데이터 프레임 입력후 새로운 변수 표현식들 입력, 생성된 변수는 데이터 프레임에 마지막 변수로 추가

#-transmute(): 생성된 변수만 유지

#예제:mtcars

#-다음 조건으로 변수 kml gp_kml을 만들고,데이터 프레임의 첫번째와 두번째 변수로 추가

#1)kml:1 mpg 0.43kml

#• 예제: mtcars

-# 다음 조건으로 변수 kml gp_kml을 만들고, 데이터 프레임의 첫 번째와 두 번째 변수로 추가

#1) kml: 1 mpg 0.43 kml

#gp_kml: kml 10 이상이면 ‘good’, 10 미만이면 ‘bad’

#2) kml: 1 mpg 0.43 kml

#gp_kml: kml 11 이상이면 ‘excellent’, 11 미만 8 이상이면 ‘good’, 8 미만이면 ‘bad'

#  - 연속형 변수를 기반으로 두 개의 범주를 갖는 범주형 변수 생성

#if_else(condition, true, false)

#condition이 만족되면 true의 값, 아니면 false의 값

library

install.packages("dplyr")

library(dplyr)

mtcars

as_tibble(mtcars) %>% mutate(kml=0.43*mpg,

                             gp_kml=if_else(kml>=10,"good","bad")) %>% relocate(kml,gp_kml)

#• 예제: mtcars

#- 다음 조건으로 변수 kml gp_kml을 만들고, 데이터 프레임의 첫 번째와 두 번째 변수로 추가

#1) kml: 1 mpg 0.43 kml

#gp_kml: kml 10 이상이면 ‘good’, 10 미만이면 ‘bad’

#2) kml: 1 mpg 0.43 kml

#gp_kml: kml 11 이상이면 ‘excellent’, 11 미만 8 이상이면 ‘good’, 8 미만이면 ‘bad’

#- 연속형 변수를 기반으로 두 개의 범주를 갖는 범주형 변수 생성

#if_else(condition, true, false) condition이 만족되면 true의 값, 아니면 false의 값

as_tibble(mtcars) %>%

  mutate(kml=0.43*mpg,

        gp_kml=if_else(kml>=10,"good","bad")) %>%

  relocate(kml,gp_kml)

#• 예제: mtcars

#2) gp_kml: kml 11 이상이면 ‘excellent’, 11 미만 8 이상이면 ‘good’, 8 미만이면 ‘bad’

#- 연속형 변수를 기반으로 3개 이상의 범주를 갖는 범주형 변수 생성

#condition_1 TRUE이면 value_1,

#condition_1 FALSE이고 condition_2 TRUE이면 value_2,

#두 조건 모두 FALSE이면 value_3

#- condition은 순서대로 평가되므로 범위를 넓혀가는 조건이 잇따라 제시

#되어야 함

#- 제시되는 조건의 개수에는 제한이 없음

#- value_1, value_2, ... 의 값은 동일한 유형

as_tibble(mtcars) %>%

  mutate(kml=0.43*mpg,

         gp_kml=case_when(

           kml<8~"bad",

           kml<11~"good",

           TRUE~"excellnt"

         )

  ) %>%

  relocate(kml,gp_kml)

         ))

#여러행 자료의 요약:summarise()

#-변수들의 요약 통계량 계산할때 유용하게 사용되는 함수

#-name=fun의 형태로 열이름과 요약 통계량을 계산하는 함수 연결

#예제:mpg

#-변수 hwy의 전체 케이스의 개수, 서로 다른 값을 갖고 있는 케이스의 개수, 평균값 계산

mpg %>% summarise(n=n(),n_hwy=n_distinct(hwy),

                  avg_hwy=mean(hwy))

#n():전체 행의 개수, n_distint():서로 다른 값을 갖고 있는 행의개수

#길이가 2이상이 되는 벡터를 결과로 출력하는 요약 통계량 함수의 사용

mpg %>% summarise(avg_hwy=mean(hwy),rng_hwy=range(hwy)) #길이가 1인 요약 통계량의 경우에만, 결과를 반복시켜 길이를 맞춰서 데이터 프레임 구성

#길이가 서로 다른 벡터로는 데이터 프레임을 구성할 수 없다.평균값/범위(최소,최대)/사분위수(0.25분위수,0.5분위수,0.75분위수)

mpg %>%

  summarise(avg_hwy = mean(hwy), rng_hwy = range(hwy),

            q_hwy = quantile(hwy, probs = c(0.25,0.5,0.75)))

#그룹 데이터 프레임의 생성: group_by()

#-한 개 이상의 변수를 이용하여 전체 데이터 프레임을 그룹으로 구분

#- 실행 결과는 tibble

#- 출력된 형태에는 큰 차이가 없으나, grouped_df라는 속성 추가

by_cyl <- mpg %>% group_by(cyl)

by_cyl

#'Groups:cyl[4]': cyl에 의하여 4개 그룹이 구성된 것을 의미

#각 그룹에 속한 자료 개수 확인

#그룹데이터 프레임 대상

by_cyl %>% tally()

#일반 데이터 프레임 대상

mpg %>% count(cyl)

#그룹 변수 추가

by_cyl %>% group_by(drv,.add = TRUE)#cyl drv로 그룹 구성

#그룹 변수 변경

by_cyl %>% group_by(drv)#drv로 그룹 구성

#그룹 해제

by_cyl %>% ungroup()

#문제들

by_cyl <- mpg %>% group_by(cyl)

by_cyl %>% tally()

by_cyl %>% group_by(drv)%>% tally()

by_cyl %>% group_by(drv, .add = TRUE) %>% tally()

by_cyl %>% ungroup() %>% tally()

# 그룹 데이터 프레임에서 기본 dplyr 함수들의 작동 방식

# 함수 summarise()

#- 각 그룹별 요약 통계량 계산

#- 예제 :

#1) 월별 변수 Ozone의 평균값

#2) 월별 Ozone의 결측값 날수와 관측된 날수

#3) 월별 첫날과 마지막 날의 Ozone

#4) 월별 Ozone의 가장 작은 값과 가장 큰 값

#5) 월별 Ozone의 개별 값이 전체 기간 동안의 평균값보다 작은 날 수

 

#다섯 문제에 공통적으로 사용될 그룹 데이터 프레임 생성

airs_M <- airquality %>% group_by(Month)

airs_M

#1) 월별 변수 Ozone의 평균값

airs_M %>%

  summarise(avg_Oz = mean(Ozone, na.rm = TRUE))

#na.rm = TRUE 결측값 포함하지 않는다는 뜻

2) 월별 Ozone의 결측값 날수와 관측된 날수

airs_M %>%

  summarise(n_miss = sum(is.na(Ozone)),n_obs = sum(!is.na(Ozone)))

3) 월별 첫날과 마지막 날의 Ozone

벡터 인덱싱 함수: first(), last(), nth()

#- first(x): x[1]과 동일

#- last(x): x[length(x)]와 동일

#- nth(x, 2): x[2]와 동일

#- nth(x, -2): x[length(x)-1]과 동일

airs_M %>%

  summarise(first_Oz = first(Ozone), last_Oz = last(Ozone))

#4) 월별 Ozone의 가장 작은 값과 가장 큰 값

airs_M %>%

  summarise(max_Oz = max(Ozone, na.rm = TRUE),

            min_Oz = min(Ozone, na.rm = TRUE))

#5) 월별 Ozone의 개별 값이 전체 기간 동안의 평균값보다 작은 날 수

m_Oz <- mean(airquality$Ozone, na.rm = TRUE)

airs_M %>%

  summarise(low_Oz = sum(Ozone < m_Oz, na.rm = TRUE))

#함수 select()- 그룹을 구성하는 변수는 선택 대상이 아니어도 항상 포함

mpg %>% group_by(cyl)  %>% select(hwy)

#함수 arrange()- 옵션 .by_group=TRUE가 추가되면 그룹 변수가 첫 번째 정렬변수

mpg %>% group_by(cyl) %>% arrange(hwy,.by_group = TRUE)

mpg %>% group_by(cyl) %>% arrange(hwy)#.by_group=TRUE를 선택하지 않으면 hwy의 순서에 따라 이루어짐

#함수 mutate() transmute()- 요약 통계량이나 순위 계산 함수 사용하여 새 변수 생성 시 다른 결과

#mean()-요약통계량 함수/min_rank()-순위 계산 함수,입력된 벡터의 (오름차순) 순위 계산. 크기가 같은 자료에는 해당되는 순위 중 가장 작은 순위를 모두에게 부여

#요약통계량 함수나 순위계산 함수는 각 그룹별로 그 결과를 계산하기 때문에 이러한 함수를 사용해서 새로운 열을 생성하는 경우에는 그룹이 구성되지 않은 데이터 프레임의 경우와 다른 결과를 생성하게 된다.

mpg %>% select(cyl, hwy) %>%

  mutate(std_hwy = hwy - mean(hwy), rank = min_rank(hwy))

mpg %>% select(cyl,hwy) %>%

  group_by(cyl) %>%

mutate(std_hwy=hwy-mean(hwy),rank=min_rank(hwy))#그룹별로 순위를 매기게 된다

#min_rank(): 입력된 벡터의 순위를 계산

:#함수 filter()

#- 요약 통계량을 사용한 조건 설정: 그룹별로 다른 조건에 의한 행 선택

mpg %>% group_by(cyl) %>%

  select(1:2,hwy) %>% #1,2열을 선택하고 hwy도 선택

  filter(hwy==max(hwy)) %>%

  arrange(hwy,.by_group = TRUE)#.by_group(TRUE): 그룹먼저배열

# 함수 slice()- 그룹별로 각각의 행 선택 가능

#airquality에서 Ozone의 월별 첫날과 마지막 날, 가장 큰 값과 가장 작은 값을 갖는 행 선택

airs_M <- airquality %>%

  group_by(Month) %>%

  select(1, 5, 6)#1열과 5 6열을 선택하는 것임

airs_M

#매달 첫날의 Ozone

airs_M %>% slice_head(Ozone,n = 1)

#매달 마지막 날 Ozone

airs_M %>% slice_tail(Ozone,n = 1)

#월별 가장 작은 Ozone

airs_M %>% slice_min(Ozone, n = 1)

#월별 가장 큰 Ozone

airs_M %>% slice_max(Ozone, n = 1)

 

#함수n() cur_data()-단독으로는 사용할 수 없고 summarise() mutate()와 함께 사용

#-n():각 그룹에 속한 행의 개수 계산

#-cur_data():각 그룹별 데이터를 따로 불러옴

#예제(skip)

#-mpg에서cyl 그룹별로 hwy를 반응 변수,displ을 설명변수로 하는 회귀모형 적합하고 결정계수 계산

#-그룹별 케이스가 5를 초과하지 않는 그룹 자료는 제외

#-회귀모형 적합: lm(y~x,data=df)데이터 프레임 df의 변수 y x의 회귀모형 적합

#-결정계수 계산: summary(lm객체)$r.squared

mpg %>% group_by(cyl) %>%

  filter(n()>5) %>%

  summarise(r2=summary(lm(hwy~displ,

                          data=cur_data()))$r.squared)

#다수의 열을 대상으로 하는 작업:across()

#-여러 열을 대상으로 동일한 작업의 반복: 모든 숫자형 변수의 평균값 계산

#-기존의 방법: 숫자형 변수 하나하나에 mean()적용->매우 번거로운 작업 방식

mtcars %>%

  summarise(mpg=mean(mpg),cyl=mean(cyl),

            disp=mean(disp),hp=mean(hp))

#-새로운 방법 : 함수across()의 활용

#dplyr 기본함수 안에서 사용

mtcars %>% summarise(across(mpg:hp,mean))

#함수 across() 사용법

#across(.cols=everything(),.fns=NULL,.names=NULL)

#.cols:<tidy-select> 방식으로 작업 대상 열 선택

#.fns: 선택된 각각의 열에 적용되는 함수 지정

#1)하나의 함수:)mean

#2)purrr 방식:)~mean(.x,na.rm=TRUE)

#3)여러함수의 리스트: )list(m=mean,miss=~sum(is.na(x)))

#names: 결과물로 생성되는 열이름 작성

#-디폴트(.fns에 하나의 함수 지정):"{col}"

#-디폴트(.fns에 여러 함수의 리스트 지정):"{col}_{fn}"

#함수summarise()와 함께 사용

#iris에서 모든 숫자형 변수의 평균값계산

iris_t<-as_tibble(iris)

iris_t %>% summarise(across(where(is.numeric),mean)) #where(is.numeric)숫자로 구성된 열들을 구한것

#iris에서 숫자형 변수는 평균, 요인은 수준의 개수

iris_t %>% summarise(across(where(is.numeric),mean),

            across(where(is.factor),nlevels))

)

#전체 행의 개수와 숫자형 변수의 표준편차

iris_t %>% summarise(n=n(),across(where(is.numeric),sd))

 

#n 150dl 아닌NA가 나온 이유 : n은 숫자이어서 across()에 의해 sd계산에 적용됨

iris_t %>% summarise(across(where(is.numeric),sd),n=n())

#n의 계싼을 across()다음으로 배치하면됨

#iris에서 "Se"로 시작하는 변수의 평균과 표준편차

iris_t %>% summarise(across(starts_with("Se"),list(M=mean,SD=sd)))

#열이름 형식 변경

iris_t %>% summarise(across(starts_with("Se"),list(M=mean,SD=sd),

                            .names="{fn}_{col}"))

#각 숫자형 변수들의 결측값 개수를 구해보자.

iris_t %>% summarise(across(where(is.numeric),~sum(is.na(.x))))

#species별로 각 숫자형 변수에서 중복되지 않는 자료 개수

iris %>% group_by(Species) %>%

  summarise(across(where(is.numeric),~length(unique(.x))))

#airquality에서 Ozone Solar.R의 평균과 표준편차

mean_sd<-list(

  mean=~mean(.x,na.rm=TRUE),

  sd=~sd(.x,na.rm=TRUE)

)

mean_sd

as_tibble(airquality) %>% summarise(across(c(                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   Solar.R),mean_sd))

#다른 기본 함수와 사용: mutate()

#-iris에서 요인을 문자형 변수로 전환

iris_t<-as_tibble(iris)

iris_t %>% mutate(across(where(is.factor),~as.character(.x)))

#-센티미터 단위로 측정된 자료를 인치 단위로 변환

iris_t %>%

  mutate(across(where(is.numeric),~.x/2.54))

#다른 기본 함수와 사용: filter()

#-iris에서 이름이 'len'이 있는 변수의 자료가 모두 6.5이상이 되는 행 선택

iris_t %>%

  filter(across(contains("Len"),~.x>=6.5))

#airquality에서 적어도 하나의 결측값이 있는 행제거

airquality %>% as_tibble() %>%

filter(across(.fns=~!is.na(.x)))

#첫번째 요소(.cols)생략,두번째 요소.fns를 반드시 표시해야함 /함수na.omit()으로도 동일한 결과

#다른 기본 함수와 사용 : distinct(),count()

#-mpg에서 처음 두 변수 manufacturer model의 자료가 중복되지 않는 행 선택

mpg %>% distinct(across(1:2),.keep_all=TRUE)

#-manufacturer model으로 구성되는 그룹에 속한 행 개수 계산하여 내림차순으로 정렬

mpg %>% count(across(1:2),sort=TRUE)

 

#행단위작업 rowwise()

#-dplyr은 열단위 작업에 특화되어있음

#-주된 분석대상은 열(변수)

#행단위 작업: 데이터 프레임의 각 행자료를 대상으로 이루어지는 작업

#-루프 연산으로 실행 가능하지만 매우 비효율적

#-함수rowwise():행단위로 그룹 구성

df1<-tibble(x=1:2,y=3:4,z=5:6)

df1 %>% rowwise()

library(dplyr)

df1

#rowwise_df라는 속성이 추가된 것임

#각 행단위로 그룹이 구성된 것임/ungroup(): 구성된 그룹 해체

#행 단위로 df1의 세변수x,y,z의 합 계산

df1  %>% rowwise()%>% mutate(total=sum(c(x,y,z)))

#함수 c_across()

#-행단위 연산에서도 많은 열을 대상으로 작업이 이루어짐

#rowwise()로 생성된 데이터 프레임을 대상으로 <tidy-select>방식으로 열을 선택하기 위한 함수

#사용법: c_across(cols=everything())

#-cols <tidy-select>방식으로 열 지정

df2<- tibble(id=1:3,w=10:12,x=20:22,y=30:32,z=40:42)

df2

df2 %>% rowwise() %>% summarise(total=sum(c_across(where(is.numeric))))

#함수 rowwise()안에 변수 지정

#-<tidy-select>방식으로 변수 지정가능

#-지정된 변수는 각행의 ID역할 수행: 연산과정에서 제외됨

df2 %>% rowwise(id) %>% mutate(total=sum(c_across(where(is.numeric))))

#데이터프레임df2의 각 열 자료를 행단위 합 total에 대한 비율로 전환

df2 %>% rowwise(id) %>%

  mutate(total=sum(c_across(where(is.numeric)))) %>%

  ungroup() %>%

  mutate(across(w:z,~.x/total))

                               

#ungroup()을 제외하고 실행해도 동일한 결과를 얻을 수 있으나 rowwise_df속성이 그대로 유지됨

                                     

#5 ggplot2에 의한 자료 시각화

#그래프 기법의 활용 예제: 보리 자료

#-자료분석과정에서 그래프의 이용이 필수적임을 보여주는 예제

#5.1 ggplot2 시작하기

#패키지 ggplot2에 있는 데이터 프레임 mpg의 변수 displ hwy의 산점도 작성

library(tidyverse)

ggplot(data=mpg)+

  geom_point(mapping=aes(x=displ,y=hwy))

#-함수 ggplot():데이터 프레임 data지정. 그래프가 작성될 비어있는 영역 확보

#-함수 geom_plot():실질적인 그래프를 작성하는 geom함수

#-geom함수 입력 요소 mapping : geom함수 내에서 항상 함수 aes()와 함께 시각적 요소를 데이터와 연결

#-ggplot안에서 mapping도 가능

#ggplot2에서 그래프 작성의 최소 요소

#-그래프 작성을 위한 법칙이 있음: 그래프의 문법

#-모든 그래프 작성에 일정하게 적용

#-익숙해지면 복잡한 형태의 그래프도 어렵지 않게 작성 가능

#그래프 작성을 위한 3가지 최소 요소: <Data>,<Geon_function>,<Mappings>

ggplot(data=<Data>)+<geom_function>(mapping=aes(<Mappings>)+<geom_function>+<geom_function(... =

#<Data>: 그래프 작성에 사용될 데이터 지정. 반드시 데이터프레임 지정.

#  <Geom_function>: 레이어(layer) 작성을 위한 geom 함수.

#- 여러 개의 geom 함수를 덧셈 기호로 연결하면 여러 레이어가 겹쳐진 그래프 작성

#-데이터를 지정할 수 있으나 지정하지 않으면

#ggplot에서 지정된 데이프레임 사용

#<Mappings>: 시각적 요소(점의 크기, 모양, 색깔, …)와 데이터 연결

#- ggplot() 으로 시작

#- geom 함수내 입력요소 mapping, 항상 aes() 사용하여 지정

#- + 를 사용하여 layers, scales, coords and facets 추가

#Layers : geom_, stat_ , position_, annotation_, …

 

#5.2 시각적 요소와 연결:Mapping

#시각적 요소

#-그래프를 시각적으로 인식할때 필요한 요소

#-산점도의 경우, 점의위치, 크기,모양 및 색깔 등이 시각적요소

#시각적 요소의 mapping setting

#-mapping: 데이터의 값과 연결되어 결정.함수aes()안에서 연결

#-setting:데이터와 관계없이 일정한 값 지정. 함수 aes()밖에서 지정

#시각적 요소의 mapping

#-기존의 그래프에 다른 변수의 정보 추가 기능

#예제: 데이터 프레임mpg의 변수 displ hwy의 산점도에 시각적 요소의 mapping으로 다른 변수 정보 추가

#-변수 class를 시각적요소color mapping

ggplot(data=mpg)+ geom_point(mapping=aes(x=displ,y=hwy,color=class))

#변수 class: 문자형 벡터

#변수 class의 값에 따라 다른색 사용

#사용된 색깔에 대한 범례는 자동적으로 추가

#색의 종류(범주의 개수)과다-> 좋은 그래프는아님

#-변수 drv를 시각적 요소 shape mapping

ggplot(data=mpg)+

  geom_point(mapping=aes(x=displ,y=hwy,shape=drv))

#shape에는 이산형 변수 mapping/변수 drv: 문자형 벡터

#변수 drv의 값에 따라 다른 모양의 점 사용/범례 자동 추가

#구분이 어려운 다른 모양의 점-> 좋은그래프는 아님

#-변수 cyl을 시각적 요소 size mapping

ggplot(data=mpg)+geom_point(mapping=aes(x=displ,y=hwy,size=cyl))

#-size mapping되는 변수는 연속형이 좋음

#-변수 cyl: 정수형 변수

#-cyl의 값에 따라 점의 크기 조절

#-범례 자동 추가

#-구분이 어려운 점 크기

#-범주의 개수 과다-> 좋은 그래프는 아님

#여러 시각적 요소를 동시에 mapping

#-변수 class color, drv shape ,cyl size mapping

ggplot(data=mpg)+

  geom_point(mapping=aes(x=displ,y=hwy,

                         color=class, shape=drv, size=cyl))

#너무 많은 정보/ 그래프의 의미가 모호

 

#시각적 요소의 setting

#-함수 aes() 밖에서 사용자가 원하는 값으로 지정

#-geom함수의 입력 요소가 됨

#시각적 요소 color,size,shape에 값 지정 법칙

#1) color: 색깔을 나타내는 문자열 지정

#2)size: 점크기를 mm단위로 지정

#3)shape: 점의 형태를 나타내는 0~26 사이의 숫자

#도형에 색깔 지정 방법

#1) 0~14의 외곽선 및 15~20의 도형색 :color사용

#2)21~25의 외곽선 : color 사용

#3) 21~25의 내부색 : fill사용

#-시각적 요소 color setting:모든 점을 빨간 색으로

ggplot(data=mpg)+

  geom_point(mapping=aes(x=displ,y=hwy),color="red")

#color를 함수 aes()밖에서 지정

#함수 geom_point()의 입력요소

#여러 시각적 요소를 동시에 setting

ggplot(data=mpg)+

  geom_point(mapping=aes(x=displ,y=hwy),color="blue",size=3,

             shape=21,fill="red",stroke=2)

#점의 모양 :shape/점의 내부 색: fill/점의 외곽선 색:size/점의 외관선 두께 조절 stroke

#함수 aes()안에서 시각적 요소에 특정 값을 setting 한 경우의 결과

ggplot(data=mpg)+geom_point(mapping=aes(x=displ,y=hwy),color="blue")

ggplot(data=mpg)+geom_point(mapping=aes(x=displ,y=hwy,color="blue"))

#mapping은 변수와의 연결을 의미/"blue"라는 값을 갖는 변수 스스로 생성, 매핑/ 하나의 값만 있는 변수에 color매핑,디폴트 색

ggplot(data=mpg)+geom_point(mapping=aes(x=displ,y=hwy))

#5.3 그룹별 그래프 작성: Facet

#범주형 변수가 다른 변수에 미치는 영향력을 그래프로 확인하는 방법

#1) 시각적 요소에 범주형 변수를 지정하여 구별: mapping

#2) 범주형 변수로 그룹 구성하고, 각그룹별 그래프 작성: faceting

#facet을 적용하기 위한 함수

#1)face_wrap():한 변수에 의한 facet

#2)facet_grid(): 한 변수 또는 두변수에 의한 facet

#함수 facet_wrap()에 의한 faceting

#-데이터를 구분하는 변수가 하나인 경우 : facet_wrap(~x)(~:R fomula표시)

#데이터 프레임mpg의 변수 displ hwy의 산점도를 class의 범주별로 작성

ggplot(data=mpg)+

  geom_point(mapping=aes(x=displ,y=hwy))+

  facet_wrap(~class)

mpg %>% select("class")

#데이터 프레임 mpg의 변수 displ hwy의 산점도를 class의 범주별로 작성(2seater케이스 제외)

mpg %>%  filter(class!="2seater") %>%

  ggplot()+

  geom_point(mapping=aes(x=displ,y=hwy))+

  facet_wrap(~class)

#패널 배치 조절

#-2x3패널 패치를 3x2배치로 수정:ncol=2

#-패널에 그래프 배치 순서를 열단위로 수정 : dir="v"

pp<-mpg %>% filter(class!="2seater") %>%

  ggplot()+

  geom_point(mapping=aes(x=displ,y=hwy))

pp+facet_wrap(~class,ncol=2)

pp+facet_wrap(~class,ncol=2,dir="v")

#함수 facet_grid()에 의한 faceting

#-한 변수에 의한 faceting:

#하나의 행으로 패널 배치: facet_grid(.~x)

#하나의 열로 패널 배치: facet_grid(x~.)

#-두 변수에 의한 faceting:facet_grid(y~x)

#행범주: 변수 y의 범주

#열 범주: 변수 x의 범주

#(y~x):~

#(.~x):1~

#(x~.):~1

#데이터 프레임 mpg에서 변수 drv cyl의 범주별로 displhwy의 산점도 작성. drv "r"인 자료와 cyl 5인 자료는 제외

my_plot<-mpg %>%

  filter(cyl!=5,drv!="r") %>%

  ggplot()+

  geom_point(mapping=aes(x=displ,y=hwy))

my_plot

my_plot+facet_grid(drv~.)

my_plot+facet_grid(.~cyl)

my_plot+facet_grid(drv~cyl)

#5.4 기하 객체:Geometric object

#base graphics에서 그래프 작성 방식:pen on paper

#높은- 수준의 그래프 함수: 좌표축과 주요 그래프 작성

#낮은- 수준의 그래프 함수: ,,문자 등을 추가하여 원하는 그래프 작성

#ggplot2에서 그래프 작성 방식

#-필요한 유형의 그래프(점 또는 선 그래프 등) 작성

#geom 함수 실행-> 해당 유형의 그래프가 작성된 layer생성

#점 그래프: geom_point()

#선 그래프: geom_line()

#작성된 그래프를 겹쳐 놓음으로써 원하는 그래프 작성

#geom함수로 작성된 layer를 차례로 겹쳐놓음

#동일 자료에 다른 geom 적용

#-mpg의 변수 displ hwy를 대상으로 point geom smooth geom적용

#--point geom : 비모수 회귀곡선 작성

ggplot(data=mpg)+

  geom_point(mapping=aes(x=displ,y=hwy))

ggplot(data=mpg)+geom_smooth(mapping=aes(x=displ,y=hwy))

#geom함수

#-현재 대략 30개 이상의 geom함수가 있음

#- 한 변수에 대한 함수: geom_bar( ), geom_histogram( ), geom_density( ), geom_dotplot( ) 등등

#- 두 변수에 대한 함수: geom_point( ), geom_smooth( ), geom_text( ), geom_line( ), geom_boxplot( ) 등등

#- 세 변수에 대한 함수: geom_contour( ), geom_tile( ) 등등

#- geom 함수의 리스트: R studio의 메뉴에서 ‘Help > Cheatsheets > Data Visualization with ggplot2’ 에서 확인 가능

 

#글로벌 매핑과 로컬 매핑

#-글로벌 매핑: 함수 ggplot()에서의 매핑. 해당 그래프 작성에 참여한 모든 geom함수에 적용

#-로컬 매핑: geom함수에서의 매핑. 해당 geom함수로 작성되는 layer에만 적용.해당 layer에서는 글로벌 매핑보다 우선해서 적용됨

ggplot(data, mapping=aes())+#글로벌 매핑

  geom_*(mapping=aes())+#로컬 매핑

  geom_*(mapping=aes())

#: mpg의 변수 dipl hwy의 산점도에 비모수 회귀곡선 추가

ggplot(data=mpg)+

  geom_point(mapping=aes(x=displ,y=hwy))+

  geom_smooth(mapping=aes(x=displ,y=hwy))

# geom함수에 동일한 내용의 매핑이 중복 입력되는 상황

#-글로벌 매핑으로 중복 입력문제 해결

ggplot(data=mpg,mapping=aes(x=displ,y=hwy))+

  geom_point()+geom_smooth()

#: mpg의 변수 displ hwy의 비모수 회귀곡선 작성. 그 위에 산점도 추가하되 drv의 값에 따라 점의 색을 구분

#비모수 회귀곡선: 전체 자료 대상

#각그룹별로 추정된 비모수 회귀

ggplot(data=mpg,mapping=aes(x=displ,y=hwy))+

  geom_point(mapping=aes(color=drv))+

  geom_smooth(se=FALSE)

#x,y:글로벌 매핑/color:로컬 매핑

ggplot(data=mpg,mapping=aes(x=displ,y=hwy,color=drv))+

  geom_point()+

  geom_smooth(se=FALSE)#x,y,color:글로벌 매핑(생성되는 모든 것에 해당)

#: mpg의 변수 displ hwy의 비모수 회귀곡선 작성하되 drv에 의해 구분되는 그룹별 각각 추정하여 선의 종류를 다르게 표시.

#그 위에 산점도 추가하되 drv의 값에 따라 점의 색을 구분, 점의 크기 확대

ggplot(data=mpg,mapping = aes(x=displ,y=hwy))+

  geom_point(mapping=aes(color=drv),size=2)+

  geom_smooth(mapping = aes(linetype=drv),se=FALSE)#se=FALSE-> 신뢰 구간을 표시하지 않음

#linetype:선의 종류를 나타내는 시각적 요소

#linetype을 지정하면 지정된 변수의 그룹별로 함수수행하고 그룹별 결과의 선 종류 다르게 표시

#지정된 변수의그룹별 함수 수행만 하려면 group을 사용

#: 다음의 그래프 작성

#-변수drv의 그룹별로 따로 비모수 회귀곡선 작성하되, 선의 색과 종류는 같은 것을 사용

ggplot(data=mpg,mapping=aes(x=displ,y=hwy))+

  geom_point()+

  geom_smooth(mapping = aes(group=drv),se=FALSE)#group:그룹을 구성하는 시각적 요소

# geom 함수에서 다른 데이터 사용

#- geom 함수로 작성되는 layer마다 다른 데이터로 그래프 작성 가능

#: mpg의 변수 displ hwy의 산점도. drv에 따라 점의 색 구분

#비모두 회귀곡선 추가하되 drv 4인 데이터 만을 대상으로 추정.

ggplot(data=mpg, mapping=aes(x=displ, y=hwy))+

  geom_point(mapping=aes(color=drv),size=2)+

  geom_smooth(data=filter(mpg, drv=="4"),

              se=FALSE,color="red")

#5.6 위치 조정:Position adjustments

# 그래프 요소들의 위치 조정

#• 연속형 자료: 산점도의 점이 겹쳐지는 경우

#• 범주형 자료: 이변량 막대 그래프 작성

# 산점도의 점이 겹치는 문제

#• 산점도 작성의 가장 큰 문제

#• 해결 방안

# 반올림 처리 등으로 같은 값이 많은 자료의 경우: 자료에 약간의 난수 추가로 점의 위치 조정(jittering)

# 이변량 막대 그래프

#• 쌓아 올린 막대 그래프 / 옆으로 붙여 놓은 막대 그래프

#산점도에서 점이 겹치는 문제 해결

#: mpg에서 변수cty hwy의 산점도 작성

ggplot(data=mpg, mapping = aes(x=cty,y=hwy))+

  geom_point()

#산점도에 나타난 점의 개수가 전체 데이터 개수인 234개에 훨씬 못 미쳐 보임

#두 변수의 값이 반올림 처리 되어 같은 값이 많아짐

#jittering-자료에 약간의 난수 추가

 

#jittering실시

ggplot(data=mpg,mapping = aes(x=cty,y=hwy))+

  geom_point(position="jitter")

#작성되는 그래프마다 미세한 차이 발생/ 추가되는 난수의 크기를 조절하고자 하는 경우에는 geom_jitter()사용

#함수 geom_jitter()

ggplot(data=mpg,mapping=aes(x=cty,y=hwy))+

  geom_jitter(width=0.4,height = 0.05)#width:좌우로 흔드는 정도/ height:상하로 흔드는 정도

ggplot(data=mpg, mapping = aes(x=cty, y=hwy))+

  geom_jitter(width=0.05, height = 0.4)

#이변량 막대 그래프작성

#- 막대그래프 작성:geom_bar()

#-이변량 막대 그래프:함수 geo_bar()에 시각적 요소 x fill,position사용

 

#예제: mpg에서 trans의범주를 auto manual로 통합한 변수am 생성/변수cyl 5인 케이스 제거 후 am cyl의 이변량 막대 그래프 작성

#자료 준비

mpg_1<- mpg %>%

  mutate(am=substr(trans,1,nchar(trans)-4)) %>%

  filter(cyl!=5)

 

#- 쌓아 올린 막대 그래프와 옆으로 붙여 놓은 막대 그래프 작성

#- geom_bar 에서 시각적 요소 x fill 에 변수 지정

#- position에 의해 이변량막대 형태 결정

p_1<-ggplot(data=mpg_1,

            mapping=aes(x=as.factor(cyl),fill=am))+

  xlab("Number of Cylinders")

library(dplyr)

library(tidyverse)

library(tidyr)

p_1+geom_bar()

#옆으로 붙여 놓은 막대 그래프

p_1+geom_bar(position="dodge")

p_1+geom_bar(position="dodge2")#차이 막대간 간격

 

#조건부 확률로 쌓아 올린 막대 그래프

p_1+geom_bar(position="fill")#position="fill":수직누적,확률표시

#cyl을 조건으로 하는 cyl am의 조건부 확률

#나란히 서있는 상자 그림

#-geom_boxplot()

#-필요한 시각적 요소: x=그룹을 구성하는 변수(요인),y=연속형변수

ggplot(data=mpg_1,mapping=aes(x=as.factor(cyl),y=hwy))+

  geom_boxplot()+

  xlab("Nuber of Cylinders")

#그룹을 구성하는 변수가 두개인 경우의 상자그림

ggplot(data=mpg_1,mapping=aes(x=as.factor(cyl),y=hwy))+

  geom_boxplot(mapping=aes(fill=am))+

  xlab("Number of Cylinders")

#변수 am에 따라 다른 색이 채워져 있고 두 상자그림이 옆에 붙어있음

#필요한 시각적 요소:x,y,fill,position

#position="dodge"가 디폴트로 적용됨

#그룹을 구성하는 변수가 두개인 경우의 상자그림

ggplot(data=mpg_1,mapping=aes(x=as.factor(cyl),y=hwy))+

  geom_boxplot()+

  xlab("Number of Cylinders")+

  facet_wrap(~am)

 

#5.7 좌표계: Coordinate system

# 좌표계: 시각적 요소 x y를 근거로 그래프의 각 요소의 2차원 위치를 결정하는 체계

# 좌표계의 종류

#• coord_cartesian( ): 디폴트

#• coord_flip( )

#• coord_polar( )

# coord_cartesian( )의 활용: XY축 범위 조정

# : mpg에서 displ hwy의 산점도에 비모수 회귀곡선 추가한 그래프 작성. X축의 범위를 (3,6)으로 축소한 그래프 작성

p<-ggplot(data=mpg,mapping=aes(x=displ,y=hwy))+

  geom_point()+geom_smooth()

p

p+coord_cartesian(xlim=c(3,6))

 

# : XY축 조정 비교

#1)함수 xlim()에 의한 조정

p+xlim(3,6)+xlab("Engine +Displacement")#범위를 벗어난 자료: 삭제

#2) 함수 coord_cartesian()에 의한 조정

p+coord_cartesian(xlim=c(3,6))+

  xlab("Engine + Displacement")#범위+ 여분

 

#함수 coord_flip( )의 활용: 평행한 상자그림 작성

#- 대부분의 geom 함수: 주어진 x 값에 대한 y의 분포 표현

#- 상자그림: 수직 방향의 작성되는 것이 디폴트

#- 수평 방향 상자그림: 디폴트 방향으로 작성하고, 그래프의 좌표를 90도 회전

#- 함수 coord_flip( ): 작성된 그래프의 좌표 회전

#:mpg에서 class의 그룹별로 hwy의 상자그림 작성

#-상자 그림: geom_boxplot()

#-x변수=class,y변수=hwy

ggplot(data=mpg,mapping=aes(x=class,y=hwy))+

  geom_boxplot()

ggplot(data=mpg,mapping=aes(x=class,y=hwy))+

  geom_boxplot()+

  coord_flip()

#)한변수(hwy)의 상자그림 작성

#- 함수geom_boxplot()에는 x y모두 필요

#-x에는 하나의 값, y에는 연속형 변수 매핑

ggplot(data=mpg, mapping=aes(x="", y=hwy)) +

  geom_boxplot() +

  xlab("")

ggplot(data=mpg, mapping=aes(x="", y=hwy)) +

  geom_boxplot() +

  xlab("") +

  coord_flip()

 

#7.1장 사용자 정의 함수

#사용자 정의함수

my_func <- function(arg1, agr2, …) {  표현식}

#my_func : 함수 이름

#arg1, arg2, … : 함수의 변수 이름

 

f <- function(x,y) x + y

f <- function(x,y){  x+y}

f(5,10)

#표현식이 한 줄인 경우: 중괄호 필요 없음

 

#함수에 입력되는 변수 종류

#1) 연산 대상이 되는 데이터(첫 번째 변수)

#2) 연산과 관련된 세부 옵션(그 이후 변수)

#디폴트값이 지정된 변수 : 함수실행에서 생략

#??? 예제: 모평균의 신뢰구간 계산하는 함수 정의

#1) 첫 번째 변수: 표본 자료

#2) 두 번째 변수: 신뢰수준

 

CI_mean <- function(x, conf=0.95){

  m <- mean(x)

  se <- sd(x)/sqrt(length(x))

  alpha <- 1-conf

  c(m-qnorm(1-alpha/2)*se, m+qnorm(1-alpha/2)*se)

}

#- 함수 qnorm( ): 정규분포 분위수 계산

 

#- 표준정규분포에 100개 난수 발생

#- 모평균에 대한 95% 신뢰구간 추정

set.seed(1234579)#seed번호지정,고정된 난수 발생

x <- rnorm(n=100)

CI_mean(x)#conf에 디폴트값 0.95지정되어있음

# conf에 디폴트값 0.95 지정되어 있슴

#- 모평균에 대한 90% 신뢰구간 추정

CI_mean(x, conf=0.9) # conf에 값 입력하면 디폴트값 0.95 무시됨

#생략 부호(…) 변수

#- 일반적으로 함수의 마지막 변수로 지정

#- 기존의 함수를 이용하여 함수를 정의하는 경우 매우 유용함

 

#: 함수 CI_mean( )

#- 자료에 NA 포함: 함수 mean(), sd()의 결과도 NA

#변수 na.rm을 함수 CI_mean()에서 사용할 방법은?

#생략 부호를 포함시킨 함수 CI_mean()

CI_mean_dot<-function(x,conf=0.95,...){

  m<-mean(x,...)

  se<-sd(x,...)/sqrt(sum(!is.na(x)))

  alpha<-1-conf

  c(m-qnorm(1-alpha/2)*se,m+qnorm(1-alpha/2)*se)

}

CI_mean_dot(y,na.rm=TRUE)

#생략부호대신 구체적인 옵션을 포함시틴 함수 CI_mean()

CI_mean_dot1<-function(x,conf=0.95,aa=F){

  m<-mean(x,na.rm = aa)

  se<-sd(x,na.rm=aa)/sqrt(sum(!is.na(x)))

  alpha<-1-conf

  c(m-qnorm(1-alpha/2)*se,m+qnorm(1-alpha/2)*se)

}

x=c(1,3,5,7,9,NA)

CI_mean_dot1(x,aa=T)

CI_mean_dot2<-function(x,conf=0.95,na.rn=F){

  m<-mean(x,na.rm = na.rm)

  se<-sd(x,na.rm=na.rm)/sqrt(sum(!is.na(x)))

  alpha<-1-conf

  c(m-qnorm(1-alpha/2)*se,m+qnorm(1-alpha/2)*se)

}

x=c(1,3,5,7,9,NA)

CI_mean_dot2(x,na.rm=T)

 

#생략부호 예제

#-두벡터를 표준화 시킨후 산점도 작성 함수 정의

my_plot<-function(x,y,...){

  z_x<-(x-mean(x))/sd(x)

  z_y<-(y-mean(y))/sd(y)

  ggplot(data.frame(x=z_x,y=z_y))+

    geom_point(aes(x,y),...)}

#-함수 my_plot()의 변수: x,y,생략부호변수

#-함수geom_point()에 생략 부호 변수 지정

#->geom_point()의 변수를 my_plot()의 변수 처럼 사용 가능

 

#데이터 프레임 cars의 변수 speed dist를 표준화하고 산점도 작성

library(ggplot2)

with(cars,my_plot(x=speed,y=dist,shape=20,

                  color="red",size=2))

#변수의 지정

#-함수의 변수를 지정하는 방법

my_power<-function(first,second){first^second}

#1)변수의 전체이름

my_power(second=5,first=2)

#2)변수의 부분이름

my_power(s=5,f=2)

#3)변수의 순서

my_power(2,5)

#결과의 출력

#함수return()에 의한 출력

#함수 return()이 없는 경우: 마지막 표현식의 실행 결과

#함수 my_desc()입력된 벡터의 평균과 표준편차를 계산하여 리스트 형태로 출력

#함수 return() 에 의한 실행 결과 출력

my_desc<-function(x,...){

  m.x<-mean(x,..);sd.x<-sd(x,...)

  res<-list(mean=m.x,sd=sd.x)

  return(res)

  }

#데이터 프레임 cars의 변수 dist의 평균, 표준편차 출력

with(cars,my_desc(x=dist))

with(airquality,my_desc(x=Ozone,na.rm=TRUE))

library(ggplot2)

 

#함수return()이 없는 함수의 결과 출력

my_desc_1<-function(x,...){

  m.x<-mean(x,...);sd.x<-sd(x,...)

  list(mean=m.x,sd=sd.x)

}

with(cars,my_desc_1(x=dist))

#마지막 표현식이 할당문이면 아무런 결과도 출력되지 않음

my_desc<-function(x,...){

  m.x<-mean(x,...);sd.x<-sd(x,...)

}

with(cars,my_desc(x=dist))

 

#주어진 조건의 만족 여부에 따라 실행되는 표현식을 다르게 하는 연산

# 함수 if( )

# 함수 ifelse( )

# 함수 switch( )

#if (조건) {표현식} #- 조건이 만족되면 표현식 실행

#if (조건) {표현식 1

} else if{  표현식 2

}else{  표현식3

}

#- 조건이 만족되면 표현식 1 실행

# 조건이 만족되지 않으면 표현식 2 실행

#"""f (조건 1) {

#  표현식 1

#} else if (조건 2) {

#  표현식 2

#} else {

#  표현식 3}

 

#함수if() 사용시 유의할점

#-if() 의조건에는 하나의 논리값만 사용됨

# : 두 벡터 x y의 구성요소를 비교하여 값이 큰 요소를 출력

x<-c(10,3,6,9)

y<-c(1,5,4,12)

if(x>y)x else y

#함수 ifelse()에 의한 조건 연산

#-사용하고자하는 조건이 하나의 논리 값이 아닌 논리 벡터의 경우

#ifelse(조건,표현식1표현식2)

#조건이 만족되면 표현식 1,만족되지 않으면 표현식 2 실행

x<-c(10,3,6,9)

y<-c(1,5,4,12)

ifelse(x>y,x,y)

#주어진 점수가 50미만이면 "Fail",50 이상이면'Pass'를 점수와 함께 출력

score<-c(80,75,40,98)

grade<-ifelse(score>=50,"Pass","Fail")

data.frame(score,grade)

#함수 switch()에 의한 조건 연산

#switch(표현식, 선택 항목 리스트)

#-표현식이 갖는 값에 따라, 선택 항목 중 선택

#-선택할 항목 리스트: 콤마로 구분된 리스트

#-표현식 값이 숫자인 경우: 선택할 항목의 위치 지정

#-표현식 값이 문자인 경우: 선택할 항목 중 항목이름이 동일한 항목 선택

#)park, lee, kim 중 한 사람 임의로 선택

(x<-sample(1:3,1))

switch(x,"Park","Lee","Kim")

switch("aa",aa="bb",bb="aa")

#: 주어진 자료의 특성을 보고 자료의 대푯값으로 평균과 중앙값중선택하는 함수 작성

my_center<-function(x,type){

  switch(type,mean=mean(x),med=median(x))

}

x<-c(1,2,3,4,50)

#함수 my_center()로 자료의 평균과 중앙값 각각 계산

my_center(x,type="med")

my_center(x,type="mean")

#복합조건

#&,|: vector element별로 조건 체크

#&&,||: vector의 첫번째 값만 체크

x=c(1,2,3,5,7,8)

 

X=runif(1)-0.5;x

if(x<0)print(abs(x))

if(x<0)print(abs(x))else print(x)

ifelse(x<0,abs(x),x)

if(x<0){print(x);print("x is negative")}else{print(x);print("x is positive")}#복합실행

if(x>=-0.5&&x<=0.5)print(x)else pring("wrong number")#복합조건

#루프연산

#프로그램의 특정 부분을 일정 횟수 반복하는 작업

#함수 for()

#함수 while()

#for 루프

#기본적인 사용법: 함수 for()

#for(var in seq){

#  표현식

#}

for(i in 1:5){print(i)}

#var: 변수이름,seq:벡터

#: 정규분포에서 10개의 임의표본을 추출하여 평균을 계산하는 과정 다섯번 반복

#-거의 동일한 명령문 다섯번 반복하는 것은 바람직하지 않음

#-비슷한 연산의 반복은 for루프 사용

res<-vector("double",5)

for(i in seq_along(res)){

  res[i]<-mean(rnorm(10))

}

#첫번째 요소: 루프 연산으로 생성될 객체를 위한 빈공간 생성

#루프 연산 중 결과값의 할당에 사용되는 인덱싱 대비

#vector("유형",길이): vector("double",5)=c(0,0,0,0,0)

#두번째 요소: 반복 횟수 및 인덱스 변수 지정

#for(var in seq):인덱스 변수 (var) seq의 값을 차례로 취하면서 루프 수행

#seq_along(x):seq(length=length(x))

#세번째 요소: 중괄호 안에서 반복 수행되는 명령문

#수행결과를 미리 확보한 벡터에 인덱싱 기법으로 할당

round(res,3)

#: 함수 for() factorial계산하고 출력

fac.x<-1

for(i in 1:5){

  fac.x<-fac.x*i

  cat(i,"!=",fac.x,"\n",sep = "")

}

#함수 cat()은 여러 개의 데이터 객체를 한데 묶어서 출력할때 유용하게 사용되는 함수

#문자열 "/n"을 입력하여 다음 연산의 결과가 새로운 줄에서 출력하도록 하였다.

#print()&cat()

#함수 print():한번에 한 객체만 출력가능

pi

print(pi)

print("원주율은",pi,"이다")

cat("원주율은 ",pi,"이다","n",sep="")#"n:줄바꿈,sep=요소구분 문자 지정

#함수 cat():벡터로만 출력 가능

y=matrix(1:4,nrow=2)

print(y)

#while()루프

#-for루프 : 반복 횟수 미리 고정

#특정 조건이 만족될때 까지 반복해야 하는 경우:for 루프 사용 불가능

#while루프: 조건이 만족되는 동안 표현식 실행

while (조건){

  표현식

}

 

i=1

while(i<=5){

  print(i)

  i=i+1

}

#함수 while() factorial 계산하고 출력

fac.x<-1

i<-1

while(i<=5){

  fac.x<-fac.x*i

  cat(i,"!=",fac.x,"\n",sep = "")

  i<-i+1

}

#연습: 1에서 5까지 각각 한개 숫자씩 더한 결과를 보여주는 프로그램

#연습: 함수 while()을 이용하여 5개의 자료 1,1,1,8,7,6의 평균을 계산하는 프로그램

sum.x=0

i=1

while(i<=5){

  sum.x=sum.x+i

  cat("sum to",i,"=",sum.x,"n",sep="")

}

#if + 루프문 연습

#연습) 1에서 10까지 정수를 더할떄 홀수는 원래 값을 더하고 짝수는 원래값의 2배를 더한 결과를 출력하라

library(tidyverse)

sum.x=0

for(i in 1:10){

  if(i %in% c(2,4,6,8,10)) sum.x=sum.x+2*i else sum.x=sum.x+i

  }

sum.x

#7.4 함수형 프로그래밍

#동일한 작업이 반복되는 상황

#루프 연산: 좋은 대안이나 프로그램 의미 파악이 어렵다는 단점

#루프 연산의 대안: 함수형 프로그래밍

#functional:함수를 입력 변수로 받는 함수

my_desc<-function(x,fun){fun(x)}

x<-rnorm(20)

my_desc(x,mean)

my_desc(x,median)

 

#중요하게 사용되는 functional의예:lapply(),sapply()

#lapply(x,FUN,...)

#-X:벡터 또는 리스트

#입력된 X의 각 요소에 FUN에 지정한 함수를 적용

#결과는 리스트

#Sapply:동일한 사용법 결과가 벡터 또는 행렬

x<-list(a1=1:5,a2=rnorm(5),a3=c(TRUE,FALSE,TRUE,FALSE))

lapply(x,mean)

sapply(x,mean)

unlist(lapply(x,mean))

 

#루프 연산과 함수형 프로그래밍의 비교

#) 평균이 -2,-1,0,1,2이고 표준편차가 0.5인 정규분포에서 10개의 임의 표본을 각각 추출하여 평균 계산

#1)루프 연산

set.seed(1234)

m<--2:2

res<-vector("double",length(m))

for (i in seq_along(res)){

  res[i]<-mean(rnorm(n=10,mean=m[i],sd=0.5))

}

res

#2)함수형 프로그래밍

#-다섯 정규분포에서 10개씩 임의표본 추출하여 리스트에 할당

#-리스트 각 요소에 평균 적용

set.seed(1234)

m<--2:2

x<-lapply(m,rnorm,n=10,sd=0.5)

sapply(x,mean)

 

#함수형 프로그래밍으로 행렬과 데이터 프레임 다루기

#행렬과 데이터 프레임을 대상으로 반복된 작업이 필요한 경우가 있음

#루프 연산보다 함수형 프로그래밍을 적용하는 것이 더 효율적

#행렬에 적용할 수 있는 functional : 함수 apply()

#apply(x,margin,fun,... )

#x:행렬 또는 배열

# MARGIN: FUN에 지정한 함수가 적용되는 방향

#MARGIN=1 행방향

#MARGIN=2 열방향

#) 세사람에 대한 반복 측정값

#A를 행렬이라고 두자.

apply(A,1,mean)#행 방향으로 평균

apply(A,2,mean)# 열방향으로 평균

apply(A,1,range)#행방향으로 최대최소 계산

 

 #그룹별 요약 통계량 계산

#데이터 프레임에 요인이 있는 경우 요인의 수준에 따라 구성되는 그룹별 다른 변수의 분포 비교는 중요한 분석

#사용가능한 방법

#1)tapply(x,INDEX,FUN,simplify=TRUE)

#X:벡터,INDEX:요인, FUN:요약 통계량을 계산하는 함수,simplify:출력형태 지정.벡터(true).리스트(false)

#2)함수 split() lapply()를 연결해서 사용

#3)dplyr group_by() summarise()을 이용

 

#):MASS Cars93에 있는 요인 Origin의 수준별 MPG.city의 평균값 비교

data(Cars94,package="MASS")

library(MASS)

#1)함수 tapply()에 의한 방법

with(Cars93, tapply(MPG.city,Origin,mean))

with(Cars93,tapply(MPG.city,Origin,mean,simplify=FALSE))

#2) 함수 split() lapply()에 의한 방법

x_g<-with(Cars93,split(MPG.city,Origin))#split(A,B):벡터 또는 데이터 프레임 A를 요인B값 별로 분리를 해서 결과는 list

str(x_g)

lapply(x_g,mean)

Cars93%>% select(MPG.city,Origin)

library(tidyverse)

lapply(x_g,mean)

#3)dplyr group_by() summarise()에 의한 방법

library(dplyr)

Cars93 %>%

  group_by(Origin) %>%

  summarise(m=mean(MPG.city),n=n())

#데이터 프레임의 모든 변수에 함수 적용

#데이터 프레임을 typeof()로 확인할때 데이터 유형은 리스트

#함수 lapply()또는 sapply()로 데이터 프레임의 각변수에 동일한 함수 적용 가능

# : 데이터 프레임airquality에서 변수 Month Day를 제외한 나머지 변수의 평균값 계산

#함수 sapply()에 의한 계산

library(dplyr)

airs<-airquality %>%

  select(-Month,-Day)

sapply(airs,mean,na.rm=TRUE)

#함수 summarise(),across()에 의한 계산

airs %>%

  summarise(across(.fns=mean,na.rm=TRUE))