반응형

[SPSS] 변수 계산 (산술 연산)

주어진 데이터의 값을 바꾸어 사용해야 할 때가 있다. 이번 포스팅에서는 다음의 연산들을 소개할 것이다.

 

산술 연산

1) 더하기

2) 빼기

3) 곱하기

4) 나누기

5) 제곱 (승)

6) 로그 (log)

7) 지수

 

*실습용 데이터는 아래 링크를 클릭하면 다운로드할 수 있습니다.

2022.08.04 - [공지사항 및 소개] - 분석용 데이터 (update 22.11.28)

 

분석용 데이터 (update 22.11.28)

2022년 11월 28일 버전입니다. 변수는 계속하여 추가될 예정입니다. 다음 카테고리에 있는 글에서 이용된 데이터입니다. - 기술 통계 - 범주형 자료 분석 - 모평균 검정 - 반복 측정 자료 분석 - 통계

medistat.tistory.com

 

데이터를 불러오도록 한다. 불러오는 방법은 다음 링크를 확인하도록 한다.

2022.08.04 - [통계 프로그램 사용 방법/SPSS] - [SPSS] 데이터 불러오기 및 저장하기

 

산술 연산을 시작하겠다.

 

변환(T) > 변수 계산(C)

 

1) 더하기

LIVER_SUM=AST+ALT : AST와 ALT값을 합쳐 LIVER_SUM이라는 변수에 저장하라.

 

2) 빼기

ALT_DIF=ALT-ALT_POSTMED : ALT에서 ALT_POSTMED를 빼서 그 값을 ALT_DIF라는 변수에 저장해라.

 

3) 곱하기

MALE_ALC=SEX*ALCOHOL : SEX와 ALCOHOL을 곱해 MALE_ALC라는 변수에 저장해라.

 

4) 나누기

LIVER_RATIO=AST/ALT; : AST를 ALT로 나누어 그 값을 LIVER_RAIO라는 변수에 저장해라

 

5) 거듭제곱 (승)

SBP_SQ=SBP**2;: SPB를 제곱하여 SBP_SQ에 저장해라. 만약 세제곱을 원한다면 "SBP**3"을 사용하면 된다.

 

6) 로그(log)

LOG_ALT=LN(ALT) : ALT에 로그를 씌워 LOG_ALT에 저장해라. 이때 로그의 밑은 $e$다.

그런데, LN과 같은 함수들을 모두 외우고 다니는 것은 비현실적이다. 이럴 때에는 "함수 집단(G)"을 클릭하면 "함수 및 특성변수(F)"에 여러 함수들이 나오게 되고 그중 하나를 클릭하면 함수 설명에 대한 글과 함께 바로 사용할 수 있게 해 주니 이를 사용하면 된다.

 

7) 지수

EXP_ALT=EXP(ALT); : $e$의 ALT승$\left( e^{ALT} \right)$을 EXP_ALT에 저장해라.

이 함수도 잘 모르겠으면 "함수 집단(G)"을 이용하면 편하게 할 수 있다.

 

 

 

연산 시 결측치는 어떻게 처리되는가?

연산 시 결측치는 어떻게 처리될까? AST가 결측치인 사람의 ALT값은 존재했다면, AST와 ALT를 더한 LIVER_SUM변수의 값은 어떻게 될까? 다음과 같이 결측치의 개수를 확인해보자. (결측치 확인 방법은 다음 링크를 확인하길 바란다. 2022.09.29 - [기술 통계/SPSS] - [SPSS] 기술 통계 (평균, 표준편차, 표준오차, 최댓값, 최솟값, 중위수, 분위수 등))

1) 분석(A)>기술통계량(E)>빈도분석(F)

 

2) 분석하고자 하는 변수들을 오른쪽으로 옮기고 "빈도표 표시(D)"박스는 반드시 해제하고, "확인" 버튼을 누른다.

 

결과

AST에는 원래 8개의 결측치가 있었는데, AST를 이용하여 산출한 변수들은 그 값을 모두 결측치로 반환하고 있음을 알 수 있다.

 

-사실 SPSS는 이러한 산술 연산이 매우 귀찮게 되어있어서 상대적으로 복잡한 분석이 필요해질 시점부터는 잘 사용하지 않게 되는 경향이 있다. 그래서 필자도 SPSS는 교육용 이외에는 거의 사용하지 않게 되었다. 

 

[SPSS] 변수 계산 (산술 연산) 정복 완료!

작성일: 2022.11.30.

최종 수정일: 2022.11.30.

이용 프로그램: IBM SPSS v26

운영체제: Windows 10

반응형
반응형

[R] 변수 계산 (산술 연산)

 주어진 데이터의 값을 바꾸어 사용해야 할 때가 있다. 이번 포스팅에서는 다음의 연산들을 소개할 것이다.

 

산술 연산

1) 더하기

2) 빼기

3) 곱하기

4) 나누기

5) 제곱 (승)

6) 로그 (log)

7) 지수

 

*실습용 데이터는 아래 링크를 클릭하면 다운로드할 수 있습니다.

2022.08.04 - [공지사항 및 소개] - 분석용 데이터 (update 22.11.21)

 

분석용 데이터 (update 22.11.21)

2022년 11월 21일 버전입니다. 변수는 계속하여 추가될 예정입니다. 다음 카테고리에 있는 글에서 이용된 데이터입니다. - 기술 통계 - 범주형 자료 분석 - 모평균 검정 - 반복 측정 자료 분석 - 통계

medistat.tistory.com

 

코드를 보여드리기에 앞서 워킹 디렉토리부터 지정하겠다.

워킹 디렉토리에 관한 설명은 다음 링크된 포스트에서 볼 수 있다.

2022.08.05 - [통계 프로그램 사용 방법/R] - [R] 작업 디렉토리 (Working Directory) 지정 - getwd(), setwd()

setwd("C:/Users/user/Documents/Tistory_blog")

 

데이터를 불러와 df에 객체로 저장하겠다.

데이터 불러오는 방법은 다음 링크에서 볼 수 있다.

2022.08.05 - [통계 프로그램 사용 방법/R] - [R] 데이터 불러오기 : EXCEL - read_excel(), read.xlsx()

2022.08.10 - [통계 프로그램 사용 방법/R] - [R] 데이터 저장하기 : CSV 파일 - write.csv(), write_csv()

2022.08.10 - [통계 프로그램 사용 방법/R] - [R] 데이터 불러오기 : SAS file (.sas7bdat) - read.sas7bdat(), read_sas()

install.packages("readr")
library("readr")
df<-read_csv("Data.csv")

 

코드

#1) 더하기
df$LIVER_SUM=df$AST+df$ALT

#2) 빼기
df$ALT_DIF=df$ALT-df$ALT_POSTMED

#3) 곱하기
df$MALE_ALC=df$SEX*df$ALCOHOL

#4) 나누기
df$LIVER_RATIO=df$AST/df$ALT

#5) 거듭제곱 (승)
df$SBP_SQ=df$SBP**2

#6) 로그 (log)
df$LOG_ALT=log(df$ALT)
df$LOG10_ALT=log(df$ALT, base=10)
df$LOG7_ALT=log(df$ALT)/log(7)

#7) 지수
df$EXP_ALT=exp(df$ALT)
df$EXP10_ALT=exp(df$ALT*log(10))

#1) 더하기
df$LIVER_SUM=df$AST+df$ALT: df 데이터의 AST와 ALT를 합쳐 그 값을 df에 LIVER_SUM이라는 변수를 새로 만들고 거기에 저장해라.

#2) 빼기
df$ALT_DIF=df$ALT-df$ALT_POSTMED : df 데이터의 ALT에서 ALT_POSTMED를 빼서 그 값을 df 데이터의 ALT_DIF이라는 변수를 새로 만들고 거기에 저장해라.

#3) 곱하기
df$MALE_ALC=df$SEX*df$ALCOHOL : SEX와 ALCOHOL을 곱해 MALE_ALC라는 변수에 저장해라.

#4) 나누기
df$LIVER_RATIO=df$AST/df$ALT : AST를 ALT로 나누어 그 값을 LIVER_RAIO라는 변수에 저장해라

#5) 거듭제곱 (승)
df$SBP_SQ=df$SBP**2 : SPB를 제곱하여 SBP_SQ에 저장해라. 만약 세제곱을 원한다면 "SBP**3"을 사용하면 된다.

#6) 로그 (log)
df$LOG_ALT=log(df$ALT) : ALT에 로그를 씌워 LOG_ALT에 저장해라. 이때 로그의 밑은 $e$다.
df$LOG10_ALT=log(df$ALT, base=10) : ALT에 로그를 씌워 LOG_ALT에 저장해라. 이때 로그의 밑은 이다.
df$LOG7_ALT=log(df$ALT)/log(7) : ALT에 로그를 씌워 LOG_ALT에 저장해라. 이때 로그의 밑은 이다. 원하는 숫자를 밑으로 하고 싶으면 7이 아닌 원하는 숫자를 적으면 된다.

#7) 지수
df$EXP_ALT=exp(df$ALT) : $e$의 ALT승을 EXP_ALT에 저장해라.
df$EXP10_ALT=exp(df$ALT*log(10)) : 10의 ALT승($10^{ALT}$)을 EXP10_ALT에 저장해라. 만약 10이 아닌 5의 ALT승를원하면 "log(5)"를 사용하면 된다.

 

연산 시 결측치는 어떻게 처리되는가?

 연산시 결측치는 어떻게 처리될까? AST가 결측치인 사람의 ALT값은 존재했다면, AST와 ALT를 더한 LIVER_SUM변수의 값은 어떻게 될까? 다음과 같이 결측치의 개수를 확인해보자. (결측치 확인 방법은 다음 링크를 확인하길 바란다. 2022.11.25 - [통계 프로그램 사용 방법/R] - [R] 결측치 확인 및 개수 확인 - is.na())

 

코드

sum(is.na(df$LIVER_SUM))

결과

8

 

즉, 산술계산을 하여도 결측치로 반환한다. 덧셈뿐 아니라 이번 포스팅에 있던 모든 산술 연산은 "결측치는 결측치로"반환한다.

 

[R] 변수 계산 (산술 연산) 정복 완료!

작성일: 2022.11.25.

최종 수정일: 2022.11.25.

이용 프로그램: R 4.2.2

RStudio v2022.07.2

RStudio 2022.07.2+576 "Spotted Wakerobin" Release

운영체제: Windows 10, Mac OS 12.6.1

반응형
반응형

[R] 결측치 확인 및 개수 확인 - is.na()

 데이터는 완벽할 수 없다. 완벽하면 좋겠지만 여러 이유로 수집되지 못하는 결측치가 존재하기 마련이다. 이 결측치를 확인하는 것은 매우 중요하다. 이번 포스팅에서는 결측치가 어디에 있는지 확인하고, 그 개수를 세보는 내용을 다루겠다.

 

*실습용 데이터는 아래 링크를 클릭하면 다운로드할 수 있습니다.

2022.08.04 - [공지사항 및 소개] - 분석용 데이터 (update 22.11.21)

 

분석용 데이터 (update 22.11.21)

2022년 11월 21일 버전입니다. 변수는 계속하여 추가될 예정입니다. 다음 카테고리에 있는 글에서 이용된 데이터입니다. - 기술 통계 - 범주형 자료 분석 - 모평균 검정 - 반복 측정 자료 분석 - 통계

medistat.tistory.com

 

코드를 보여드리기에 앞서 워킹 디렉토리부터 지정하겠다.

워킹 디렉토리에 관한 설명은 다음 링크된 포스트에서 볼 수 있다.

2022.08.05 - [통계 프로그램 사용 방법/R] - [R] 작업 디렉토리 (Working Directory) 지정 - getwd(), setwd()

setwd("C:/Users/user/Documents/Tistory_blog")

 

데이터를 불러와 df에 객체로 저장하겠다.

데이터 불러오는 방법은 다음 링크에서 볼 수 있다.

2022.08.05 - [통계 프로그램 사용 방법/R] - [R] 데이터 불러오기 : EXCEL - read_excel(), read.xlsx()

2022.08.10 - [통계 프로그램 사용 방법/R] - [R] 데이터 저장하기 : CSV 파일 - write.csv(), write_csv()

2022.08.10 - [통계 프로그램 사용 방법/R] - [R] 데이터 불러오기 : SAS file (.sas7bdat) - read.sas7bdat(), read_sas()

install.packages("readr")
library("readr")
df<-read_csv("Data.csv")

 

코드 - 결측치 위치 확인

is.na(df)

is.na(df) : 결측치는 "TRUE"를, 결측치가 아니면 "FALSE"를 반환하는 함수를 데이터 df에 적용하라

결과

        IDNO   SEX  SMOK ALCOHOL RESID  TWIN    RH   HTN   SBP   ALT   AST ALT_POSTMED FVC_pPRED TRANSPORT
   [1,] FALSE FALSE FALSE   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE       FALSE     FALSE     FALSE
   [2,] FALSE FALSE FALSE   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE       FALSE     FALSE     FALSE
   [3,] FALSE FALSE FALSE   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE       FALSE     FALSE     FALSE
   [4,] FALSE FALSE FALSE   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE       FALSE     FALSE     FALSE
   [5,] FALSE FALSE FALSE   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE       FALSE     FALSE     FALSE
   [6,] FALSE FALSE FALSE   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE       FALSE     FALSE     FALSE
   [7,] FALSE FALSE FALSE   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE       FALSE     FALSE     FALSE
   [8,] FALSE FALSE FALSE   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE       FALSE     FALSE     FALSE
   [9,] FALSE FALSE FALSE   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE       FALSE     FALSE     FALSE
  [10,] FALSE FALSE FALSE   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE       FALSE     FALSE     FALSE

결과창 중 일부만 가져왔다. 1000명에 대한 데이터이므로 행의 개수는 1000개인데 그 중 10개만 가져온 것이다.

결측치는 TRUE로 반환했을 것인데, 여기까지는 결측치가 보이지 않는다.

 

 결측치가 몇 개인지 알고 싶은데, 이 1000개를 들여다보는 것은 말은 안 된다. 이때 다음 코드를 쓰면 개수를 구할 수 있다.

코드 - 결측치 개수 확인

sum(is.na(df))

sum(is.na(df)) : is.na(df)에서 TRUE인 것의 개수를 계산하라.

결과

8

8개가 결측치임을 알 수 있다.

 

 

 

그럼 만약에 변수별로 결측치의 개수를 확인하고 싶다면 어떻게 해야할까? 만약 AST의 결측치 개수를 보고 싶다면 다음 코드를 시행하면 된다.

코드

sum(is.na(df$AST))

결과

8

 

 

[R] 결측치 확인 및 개수 확인 정복 완료!

작성일: 2022.11.25.

최종 수정일: 2022.11.25.

이용 프로그램: R 4.2.2

RStudio v2022.07.2

RStudio 2022.07.2+576 "Spotted Wakerobin" Release

운영체제: Windows 10, Mac OS 12.6.1

반응형
반응형

[R] 변수의 유형 (타입, type) 확인 및 변경 - as.factor(), as.numeric(), str()

 

변수는 보통 다음 네 가지의 종류로 나누곤 한다.

 

1) 명목 척도: 범주형, 순서 없음

 예시) 성별 - "남성", "여성"

2) 순서 척도: 범주형, 순서 있음

 예시) 암의 병기 - "1기", "2기", "3기", "4기"

3) 등간 척도: 연속형, 곱셈 불가

 예시) IQ 점수 - IQ가 150인 사람보다 100인 사람은 50점이 더 높다. 100점인 사람이 50점인 사람도 똑같이 50점이 더 높다. 하지만 100점인 사람이 50점보다 두 배 더 똑똑하다고 할 수는 없다.

4) 비율 척도: 연속형, 곱셈 가능

 예시) 나이 - "1세", "55세",...

 

그런데, 학문적으로 저렇게 나눈다고 하여도, 의학 통계를 하는 사람에게 저렇게 세분하는 것이 그렇게까지 중요한 것은 아니다. 단지 우리에게는 범주형 (비연속형, 이산형) 변수와 연속형 변수가 있다는 사실만이 중요하다. 이번 포스팅에서는 변수의 형태를 확인하고, 원하는 경우 다른 유형으로 변경하는 방법에 대해 알아보겠다.

 

*실습용 데이터는 아래 링크를 클릭하면 다운로드할 수 있습니다.

2022.08.04 - [공지사항 및 소개] - 분석용 데이터 (update 22.11.21)

 

분석용 데이터 (update 22.11.21)

2022년 11월 21일 버전입니다. 변수는 계속하여 추가될 예정입니다. 다음 카테고리에 있는 글에서 이용된 데이터입니다. - 기술 통계 - 범주형 자료 분석 - 모평균 검정 - 반복 측정 자료 분석 - 통계

medistat.tistory.com

 

코드를 보여드리기에 앞서 워킹 디렉토리부터 지정하겠다.

워킹 디렉토리에 관한 설명은 다음 링크된 포스트에서 볼 수 있다.

2022.08.05 - [통계 프로그램 사용 방법/R] - [R] 작업 디렉토리 (Working Directory) 지정 - getwd(), setwd()

setwd("C:/Users/user/Documents/Tistory_blog")

 

데이터를 불러와 df에 객체로 저장하겠다.

데이터 불러오는 방법은 다음 링크에서 볼 수 있다.

2022.08.05 - [통계 프로그램 사용 방법/R] - [R] 데이터 불러오기 : EXCEL - read_excel(), read.xlsx()

2022.08.10 - [통계 프로그램 사용 방법/R] - [R] 데이터 저장하기 : CSV 파일 - write.csv(), write_csv()

2022.08.10 - [통계 프로그램 사용 방법/R] - [R] 데이터 불러오기 : SAS file (.sas7bdat) - read.sas7bdat(), read_sas()

install.packages("readr")
library("readr")
df<-read_csv("Data.csv")

 

데이터 유형 확인하기 - str()

코드

데이터에 있는 변수들의 유형을 확인할 때에는 str()이라는 함수를 쓴다. 내장함수이므로 별도 패키지의 설치가 필요 없다.

str(df)

 

결과

spc_tbl_ [1,000 × 14] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
 $ IDNO       : num [1:1000] 1 2 3 4 5 6 7 8 9 10 ...
 $ SEX        : num [1:1000] 0 0 0 0 1 1 1 1 0 1 ...
 $ SMOK       : num [1:1000] 1 2 0 0 2 1 1 1 1 0 ...
 $ ALCOHOL    : num [1:1000] 1 1 0 0 1 1 1 1 1 0 ...
 $ RESID      : num [1:1000] 1 2 2 0 1 2 0 2 0 0 ...
 $ TWIN       : num [1:1000] 0 0 0 0 0 0 0 0 0 0 ...
 $ RH         : num [1:1000] 1 1 1 1 1 1 1 1 1 1 ...
 $ HTN        : num [1:1000] 1 1 0 1 1 0 0 0 1 0 ...
 $ SBP        : num [1:1000] 142 151 120 148 165 ...
 $ ALT        : num [1:1000] 39.1 37.4 31.4 19.7 35.6 ...
 $ AST        : num [1:1000] 45.7 37.4 33.6 23.4 27.6 ...
 $ ALT_POSTMED: num [1:1000] 38.4 28.6 34.9 32.8 32 ...
 $ FVC_pPRED  : num [1:1000] 73.4 54.7 121.5 77.6 91.6 ...
 $ TRANSPORT  : chr [1:1000] "도보" "도보" "도보" "도보" ...

하나씩 살펴보면 다음과 같다.

맨 앞에 있는 "IDNO", "SEX", "SMOK", "ALCOHOL", ... ,"TRNASPORT"는 변수의 이름이다.

"IDNO"부터 "FVC_pPRED"까지는 num이라고 적혀있다. 이는 numeric의 약자이며, 숫자형 (연속형) 변수임을 의미한다.

"TRANSPORT"는 chr이라고 적혀있다. 이는 character의 약자이며, 문자형 변수임을 의미한다.

 

그런데, 서두에 우리는 변수를 범주형, 연속형 변수로 나누기로 했다. 그런데, 숫자로 이루어진 변수는 모두 연속형 변수로 취급되고 있고, 문자가 들어간 변수는 그저 문자형 변수로 취급되고 있다. 그런데 이는 적절하지 않다. 예를 들어 성별을 나타내는 "SEX"변수는 1과 2로 이루어진 범주형 변수다. 여성을 나타내는 0이 남성을 나타내는 1보다 작다고 할 수 없는 것이다. 그저 숫자로 나타낸 것 뿐이다. 여성을 2로 나타낼 수도 있었는데, 그렇다고 하여 여성이 남성보다 크다고 할 수는 없는 것이다.

 

 코드북을 살펴보면 알 수 있지만, 다음과 같이 변수를 구분할 수 있다.

변수명 변수 종류
SEX 범주형
SMOK 범주형
ALCOHOL 범주형
RESID 범주형
TWIN 범주형
RH 범주형
HTN 범주형
SBP 연속형
ALT 연속형
AST 연속형
ALT_POST 연속형
FVC_pPRED 연속형
TRANSPORT 범주형

 

따라서, "IDNO", "SEX", "SMOK", "ALCOHOL", "RESID", "TWIN", "RH", "HTN", "TRANSPORT"는 범주형 자료로 바꿔주어야 한다. 이럴 때에는 범주형 변수로 바꾸어주는 as.factor() 함수를 사용해야 한다.

 

범주형 변수로 바꾸기 - as.factor()

코드

df$SEX<-as.factor(df$SEX)
df$SMOK<-as.factor(df$SMOK)
df$ALCOHOL<-as.factor(df$ALCOHOL)
df$RESID<-as.factor(df$RESID)
df$TWIN<-as.factor(df$TWIN)
df$RH<-as.factor(df$RH)
df$HTN<-as.factor(df$HTN)
df$TRANSPORT<-as.factor(df$TRANSPORT)

df$SEX<-as.factor(df$SEX) df 데이터의 "SEX"변수를 범주형으로 바꾸어 df 데이터의 "SEX"변수로 저장하라. 이미 SEX변수가 있으므로 덮어쓰도록 한다.

 

다시 str() 함수를 사용하여 변수의 종류를 확인해보면 다음과 같이 변한 것을 알 수 있다.

코드

str(df)

 

결과

$ IDNO       : num [1:1000] 1 2 3 4 5 6 7 8 9 10 ...
 $ SEX        : Factor w/ 2 levels "0","1": 1 1 1 1 2 2 2 2 1 2 ...
 $ SMOK       : Factor w/ 3 levels "0","1","2": 2 3 1 1 3 2 2 2 2 1 ...
 $ ALCOHOL    : Factor w/ 2 levels "0","1": 2 2 1 1 2 2 2 2 2 1 ...
 $ RESID      : Factor w/ 3 levels "0","1","2": 2 3 3 1 2 3 1 3 1 1 ...
 $ TWIN       : Factor w/ 3 levels "0","1","2": 1 1 1 1 1 1 1 1 1 1 ...
 $ RH         : Factor w/ 2 levels "0","1": 2 2 2 2 2 2 2 2 2 2 ...
 $ HTN        : Factor w/ 2 levels "0","1": 2 2 1 2 2 1 1 1 2 1 ...
 $ SBP        : num [1:1000] 142 151 120 148 165 ...
 $ ALT        : num [1:1000] 39.1 37.4 31.4 19.7 35.6 ...
 $ AST        : num [1:1000] 45.7 37.4 33.6 23.4 27.6 ...
 $ ALT_POSTMED: num [1:1000] 38.4 28.6 34.9 32.8 32 ...
 $ FVC_pPRED  : num [1:1000] 73.4 54.7 121.5 77.6 91.6 ...
 $ TRANSPORT  : Factor w/ 3 levels "대중교통","도보",..: 2 2 2 2 1 1 2 3 1 1 ...

위에서 "IDNO", "SEX", "SMOK", "ALCOHOL", "RESID", "TWIN", "RH", "HTN", "TRANSPORT"의 변수 형태는 "num"이었는데 "Factor"로 바뀐 것을 알 수 있다.

 "SMOK"는 "Factor w/ 3 levels"이라고 적혀있는데, 이는 "Factor with 3 levels"의 약자로 "범주형 변수인데, 3개의 범주가 존재한다"는 뜻이다. 실제로도 '비흡연자', '과거 흡연자', '현재 흡연자'로 나누어놨으니 맞게 변환된 것을 알 수 있다.

 

연속형 변수, 문자형 변수로 바꾸기 - as.numeric(), as.character()

위와 같이 바꾸고 나서 가끔은 다시 연속형 변수로 바꾸거나 문자형 변수로 되돌려야 할 때가 있을 수 있다. 이때는 각각 as.numeric()과 as.character() 함수를 사용하면 된다. "RESID" 변수를 연속형 변수로, "TRANSPORT"변수를 문자형 변수로 되돌려보자.

 

코드

df$RESID<-as.numeric(df$RESID)
df$TRANSPORT<-as.character(df$TRANSPORT)

 

다시 str() 함수를 사용하여 변수의 종류를 확인해보면 원하는 대로 변한 것을 알 수 있다.

코드

str(df)

 

결과

 $ IDNO       : num [1:1000] 1 2 3 4 5 6 7 8 9 10 ...
 $ SEX        : Factor w/ 2 levels "0","1": 1 1 1 1 2 2 2 2 1 2 ...
 $ SMOK       : Factor w/ 3 levels "0","1","2": 2 3 1 1 3 2 2 2 2 1 ...
 $ ALCOHOL    : Factor w/ 2 levels "0","1": 2 2 1 1 2 2 2 2 2 1 ...
 $ RESID      : num [1:1000] 2 3 3 1 2 3 1 3 1 1 ...
 $ TWIN       : Factor w/ 3 levels "0","1","2": 1 1 1 1 1 1 1 1 1 1 ...
 $ RH         : Factor w/ 2 levels "0","1": 2 2 2 2 2 2 2 2 2 2 ...
 $ HTN        : Factor w/ 2 levels "0","1": 2 2 1 2 2 1 1 1 2 1 ...
 $ SBP        : num [1:1000] 142 151 120 148 165 ...
 $ ALT        : num [1:1000] 39.1 37.4 31.4 19.7 35.6 ...
 $ AST        : num [1:1000] 45.7 37.4 33.6 23.4 27.6 ...
 $ ALT_POSTMED: num [1:1000] 38.4 28.6 34.9 32.8 32 ...
 $ FVC_pPRED  : num [1:1000] 73.4 54.7 121.5 77.6 91.6 ...
 $ TRANSPORT  : chr [1:1000] "도보" "도보" "도보" "도보" ...

 

 

만약, 이 모든 것을 출력하고 싶지 않으면 (특히 변수가 많은 데이터의 경우 더더욱 그렇다) 특정 변수의 형태만 확인할 수도 있다.

"RESID"와 "TRANSPORT"의 형태를 확인해보자.

 

코드

str(df$RESID)
str(df$TRANSPORT)

 

결과

 num [1:1000] 2 3 3 1 2 3 1 3 1 1 ...
 
 chr [1:1000] "도보" "도보" "도보" "도보" "대중교통" ...

각각 "numeric"과 "character"로 나타나는 것을 알 수 있다.

 

코드 정리

#워킹 디렉토리 지정
setwd("C:/Users/user/Documents/Tistory_blog")

#데이터 불러오기
install.packages("readr")
library("readr")
df<-read_csv("Data.csv")

#데이터 변수 유형 확인하기
str(df)

#범주형 변수로 변경하기
df$SEX<-as.factor(df$SEX)
df$SMOK<-as.factor(df$SMOK)
df$ALCOHOL<-as.factor(df$ALCOHOL)
df$RESID<-as.factor(df$RESID)
df$TWIN<-as.factor(df$TWIN)
df$RH<-as.factor(df$RH)
df$HTN<-as.factor(df$HTN)
df$TRANSPORT<-as.factor(df$TRANSPORT)

#숫자형 변수로 변경하기
df$RESID<-as.numeric(df$RESID)

#문자형 변수로 변경하기
df$TRANSPORT<-as.character(df$TRANSPORT)

#특정 변수의 유형만 확인하기
str(df$RESID)
str(df$TRANSPORT)

 

 

참고로, as.factor()가 아닌 factor()라는 함수도 존재한다. 기능은 같으나 as.factor()가 특정 상황에서 조금 더 빠르게 작동하여 as.factor()를 본문에서는 소개했지만, factor() 함수를 사용해도 같은 결과를 내니 원하는 것을 사용하면 된다.

 

 

 

[R] 변수의 유형 (타입, type) 확인 및 변경 정복 완료!

 

작성일: 2022.11.21.

최종 수정일: 2022.11.21.

이용 프로그램: R 4.2.2

RStudio v2022.07.2

RStudio 2022.07.2+576 "Spotted Wakerobin" Release

운영체제: Windows 10, Mac OS 12.6.1

반응형
반응형

조건에 맞는 자료 추출하기

 

 조건에 맞는 자료만 따로 뽑아서 보고 싶을 때, 봐야 할 때가 존재한다. 가령 전체 데이터 중에서 고혈압 환자와, 정상인 환자를 따로따로 보고 싶을 때가 있듯이 말이다. 이때 할 수 있는 방법을 설명하고자 한다.

 

 총 네 가지 방법을 소개할 것이다.

(1) R 내장 함수를 사용하는 방법: 3가지
(2) dplyr을 사용하는 방법: 1가지

 

*실습용 데이터는 아래 링크를 클릭하면 다운로드할 수 있습니다.

2022.08.04 - [공지사항 및 소개] - 분석용 데이터 (update 22.10.11)

 

분석용 데이터 (update 22.10.11)

2022년 10월 11일 버전입니다. 변수는 계속하여 추가될 예정입니다. 다음 카테고리에 있는 글에서 이용된 데이터입니다. - 기술 통계 - 범주형 자료 분석 - 모평균 검정 - 반복 측정 자료 분석 - 통계

medistat.tistory.com

 

코드를 보여드리기에 앞서 워킹 디렉토리부터 지정하겠다.

워킹 디렉토리에 관한 설명은 다음 링크된 포스트에서 볼 수 있다.

2022.08.05 - [통계 프로그램 사용 방법/R] - [R] 작업 디렉토리 (Working Directory) 지정 - getwd(), setwd()

setwd("C:/Users/user/Documents/Tistory_blog")

 

데이터를 불러와 df에 객체로 저장하겠다.

데이터 불러오는 방법은 다음 링크에서 볼 수 있다.

2022.08.05 - [통계 프로그램 사용 방법/R] - [R] 데이터 불러오기 : EXCEL - read_excel(), read.xlsx()

2022.08.10 - [통계 프로그램 사용 방법/R] - [R] 데이터 저장하기 : CSV 파일 - write.csv(), write_csv()

2022.08.10 - [통계 프로그램 사용 방법/R] - [R] 데이터 불러오기 : SAS file (.sas7bdat) - read.sas7bdat(), read_sas()

 

install.packages("readr")
library("readr")
df<-read_csv("Data.csv")

 

목표: 고혈압이 있는 사람과 정상인 사람으로 데이터를 나눠보자

방법 (1) R 내장 함수를 사용하는 방법

 1. Indexing을 이용하는 방법

df_whtn<-df[df$HTN==1,]
df_wohtn<-df[df$HTN==0,]

df_whtn<-df[df$HTN==1,] df에서 HTN이 1인 행만 추출하여 df_whtn에 저장한다. (행이라서 쉼표 앞에 조건이 붙는다.) 
df_wohtn<-df[df$HTN==0,] df에서 HTN이 0인 행만 추출하여 df_wohtn에 저장한다. (행이라서 쉼표 앞에 조건이 붙는다.) 

 

 

2. which함수를 이용하는 방법

df_whtn1<-df[which(df$HTN==1),]
df_wohtn1<-df[which(df$HTN==0),]

df_whtn2<-df[which(df$HTN==1),] df에서 HTN이 1인 행만 추출하여 df_whtn1에 저장한다. (행이라서 쉼표 앞에 조건이 붙는다.) 
df_wohtn2<-df[which(df$HTN==0),] df에서 HTN이 0인 행만 추출하여 df_wohtn1에 저장한다. (행이라서 쉼표 앞에 조건이 붙는다.) 

 

 

3. subset함수를 이용하는 방법

df_whtn2<-subset(df,HTN==1)
df_wohtn2<-subset(df,HTN==0)

df_whtn2<-subset(df,HTN==1) df에서 HTN이 1인 행만 추출하여 df_whtn2에 저장한다. 
df_wohtn2<-subset(df,HTN==0) df에서 HTN이 0인 행만 추출하여 df_wohtn2에 저장한다. 

 

방법 (2) dplyr를 사용하는 방법

이를 위해서는 dplyr패키지의 설치가 필요하다. 설치에 관한 내용은 다음 글을 확인하길 바란다. 2022.08.05 - [통계 프로그램 사용 방법/R] - [R] 패키지 설치하기 - install.packages(), library()

install.packages("dplyr")
library("dplyr")

#조건에 따라 나누기
df_whtn3<-df %>% filter(HTN==1)
df_wohtn3<-df %>% filter(HTN==0)

df_whtn3<-df %>% filter(HTN==1) df에서 HTN이 1인 행만 추출하여 df_whtn3에 저장한다. 
df_wohtn3<-df %>% filter(HTN==0) df에서 HTN이 0인 행만 추출하여 df_wohtn3에 저장한다. 

 

"%>%"은 dplyr에서 chain operation이라고 불리는 연산자인데, Ctrl(Cmd for mac) + Shift + M이라는 단축키로 입력할 수 있고, 처음에는 어색해 보일 수 있지만 쓰다 보면 이렇게 편한 연산자가 없다. 이는 생각의 흐름대로 분석을 할 수 있게 해 준다.

 이 경우, "데이터 df을 가져와서 HTN1인 데이터만 고르는 필터링을 하라."로 이해할 수 있다.

 

[R] 조건에 맞는 자료 추출하기 정복 완료!

 

작성일: 2022.11.10.

최종 수정일: 2022.11.10.

이용 프로그램: R 4.1.3

RStudio v1.4.1717

RStudio 2021.09.1+372 "Ghost Orchid" Release 

운영체제: Windows 10, Mac OS 10.15.7

반응형
반응형

[R] 피셔 정확 검정에서 workspace 부족 에러 해결 방법

 

피셔 정확 검정 (Fisher's exact test)을 R로 구현하다 보면 다음과 같은 에러가 뜰 때가 있다.

 

1)

  FEXACT error 6.  LDKEY=592 is too small for this problem,   (ii := key2[itp=867] = 369304672, ldstp=17760)

Try increasing the size of the workspace and possibly 'mult'

 

2)

 FEXACT error 40. Out of workspace.

 

이럴 때에는 workspace를 늘려주어야 분석이 가능해진다.

Fisher's exact test를 시행하는 R 코드에서 다음과 같이 (workspace=2e8) 혹은 (workspace=2e9), ...과 같은 argument를 추가해주면 구동될 '수도' 있다. Fisher's exact test를 시행하는 R코드는 다음 링크에서 확인할 수 있다. 2022.09.02 - [범주형 자료 분석/R] - [R] 피셔 정확 검정 - fisher.test()

*실습용 데이터는 아래 링크를 클릭하면 다운로드할 수 있습니다.

2022.08.04 - [공지사항 및 소개] - 분석용 데이터 (update 22.10.11)

 

분석용 데이터 (update 22.10.11)

2022년 10월 11일 버전입니다. 변수는 계속하여 추가될 예정입니다. 다음 카테고리에 있는 글에서 이용된 데이터입니다. - 기술 통계 - 범주형 자료 분석 - 모평균 검정 - 반복 측정 자료 분석 - 통계

medistat.tistory.com

 

 

코드를 보여드리기에 앞서 워킹 디렉토리부터 지정하고 데이터를 불러와 df에 객체로 저장하겠다.

워킹 디렉토리에 관한 설명은 다음 링크된 포스트에서 볼 수 있다.

2022.08.05 - [통계 프로그램 사용 방법/R] - [R] 작업 디렉토리 (Working Directory) 지정 - getwd(), setwd()

 

데이터 불러오는 방법은 다음 링크에서 볼 수 있다.

2022.08.05 - [통계 프로그램 사용 방법/R] - [R] 데이터 불러오기 : EXCEL - read_excel(), read.xlsx()

2022.08.10 - [통계 프로그램 사용 방법/R] - [R] 데이터 저장하기 : CSV 파일 - write.csv(), write_csv()

2022.08.10 - [통계 프로그램 사용 방법/R] - [R] 데이터 불러오기 : SAS file (.sas7bdat) - read.sas7bdat(), read_sas()

 

 

(workspace=2e8) 혹은 (workspace=2e9), ...과 같은 argument를 추가하여 코드를 실행해보겠다.

#작업 디렉토리 지정
setwd("C:/Users/user/Documents/Tistory_blog")

#데이터 불러오기
install.packages("readr")
library("readr")
df<-read_csv("Data.csv")

#피셔 정확 검정 시행하기
fisher.test(df$SEX, df$RH, workspace=2e8)

 

물론 우리의 데이터는 그렇게 크지 않아 workspace가 부족하지 않으며, workspace를 늘려줄 필요도 없다. 하지만 만약 여러분의 데이터로 피셔 정확 검정을 시행하던 차에 저런 문제가 생기는 경우 workspace를 늘려보기를 권한다.

 

[R] 피셔 정확 검정 workspace 에러 해결 방법 정복 완료!

 

작성일: 2022.11.10.

최종 수정일: 2022.11.10.

이용 프로그램: R 4.1.3

RStudio v1.4.1717

RStudio 2021.09.1+372 "Ghost Orchid" Release 

운영체제: Windows 10, Mac OS 10.15.7

반응형
반응형

[SAS] 변수 계산 (비교 연산) - DATA, SET, GE, LE, NE, IN, MIN, MAX

조건에 따라 변수를 바꾸고 싶을 때가 있다. 예를 들어, 인구를 1) AST 40 이상, 2) AST 20 이상 40 미만, 3) AST 20 미만으로 나누고 싶을 수 있다. 이런 경우에 사용하는 비교 연산에 대해 알아보고자 한다. 내용은 다음과 같다.

 

1) >, <, >=, <=, =, ^=

2) MAX

3) MIN

4) IN, NOT IN

 

*실습용 데이터는 아래 링크를 클릭하면 다운로드할 수 있습니다.

2022.08.04 - [공지사항 및 소개] - 분석용 데이터 (update 22.10.06)

 

분석용 데이터 (update 22.10.06)

2022년 08월 29일 버전입니다. 변수는 계속하여 추가될 예정입니다. 다음 카테고리에 있는 글에서 이용된 데이터입니다. - 기술 통계 - 통계 프로그램 사용 방법 1) 엑셀 파일 2) CSV 파일 3) 코드북

medistat.tistory.com

시작하기 위해 라이브러리를 만들고, 파일을 불러온다.

라이브러리 만드는 방법: 2022.08.05 - [통계 프로그램 사용 방법/SAS] - [SAS] 라이브러리 만들기 - LIBNAME

파일 불러오는 방법: 2022.08.05 - [통계 프로그램 사용 방법/SAS] - [SAS] 데이터 불러오기 및 저장하기 - PROC IMPORT, PROC EXPORT

 

*라이브러리 지정하기;
LIBNAME hong "C:/Users/User/Documents/Tistory_blog";

*파일 불러오기;
PROC IMPORT
DATAFILE="C:\Users\user\Documents\Tistory_blog\Data.xlsx"
DBMS=EXCEL
OUT=hong.df
REPLACE;
RUN;

 

상황: 전체 인구를 1) AST 40 이상, 2) AST 20 이상 40 미만, 3) AST 20 미만으로 나누고 싶을 때

 AST는 연속 변수로 코딩되어 있음을 코드북에서 확인할 수 있다. 우리는 ALT_S3이라는 변수를 새로 만들어 다음과 같이 코딩되기를 바란다.

AST_S2 0 1 2
AST 40 이상 20 이상 40 미만 20 미만

 이를 실행하는 방법은 여러 가지가 있는데, 코드를 하나씩 살펴보면 다음과 같다. 변수를 바꿀 때 쓰는 DATA-SET구문에 대한 설명은 다음 링크를 확인하길 바란다. 2022.10.06 - [통계 프로그램 사용 방법/SAS] - [SAS] 변수 계산 (산술 연산) - DATA, SET

 

가장 기초적인 방법 (하지만 잘못된 코드다)

DATA hong.df_new;
SET hong.df;

*AST를 기준으로 셋으로 나누기;
IF AST>=40 THEN AST_S3=0;
	ELSE IF AST<40 AND AST>=20 THEN AST_S3=1;
	ELSE IF AST<20 THEN AST_S3=2;

RUN;

조건문 (IF, ELSE IF)와 AND 연산자에 대한 내용은 다음 링크를 확인하길 바란다. 2022.10.06 - [통계 프로그램 사용 방법/SAS] - [SAS] 변수 계산 (논리 연산) - DATA, SET, IF, ELSE IF, ELSE, AND, OR

 

IF AST>=40 THEN AST_S3=0; : AST가 40 이상이면 AST_S3의 값은 0을 부여한다.
     ELSE IF AST<40 AND AST>=20 THEN AST_S3=1; : AST가 40 미만이면서 20 이상이면 AST_S3의 값은 1을 부여한다.
     ELSE IF AST<20 THEN AST_S3=2; : AST가 20 미만이면 AST_S3의 값은 2를 부여한다.

 

 

문제점: 결측치

얼핏 보면 이상할 것이 없어 보이는 이 코드가 왜 잘못되었다고 하는 것일까?

문제는 결측치다.

 

다음 코드로 AST의 분포를 확인해보면 8개의 결측치가 있음을 알 수 있다. PROC MEANS에 관한 내용은 다음 링크에서 확인할 수 있다. 2022.09.23 - [기술 통계/SAS] - [SAS] 기술 통계 (평균, 표준편차, 표준오차, 최댓값, 최솟값, 중위수, 분위수 등) - PROC UNIVARIATE, PROC MEANS

 

결측치 확인 코드

PROC MEANS DATA=hong.df NMISS; 
VAR AST; 
RUN;

 

결과

 

결측치 확인 코드

그런데, AST_S3에는 결측치가 없음을 다음 코드에서 확인할 수 있다.

PROC MEANS DATA=hong.df_new NMISS; 
VAR AST_S3; 
RUN;

 

결과

 

결측치 향방 확인하는 코드

그렇다면 결측치는 모두 어디에 가있는 것일까? SAS에서는 결측치를 "."으로 표현한다. 결측치를 1로, 결측치가 아닌 경우를 0으로 코딩한 변수 AST_MISS를 만들고, AST_S3과의 분할표를 만들어 확인해보자. 분할표에 대한 내용은 다음 링크를 확인하길 바란다. 2022.08.18 - [기술 통계/SAS] - [SAS] 도수분포표 (Frequency table), 분할표 (Contingency table) 만들기 - PROC FREQ

DATA hong.df_new;
SET hong.df;

*AST를 기준으로 셋으로 나누기;
IF AST>=40 THEN AST_S3=0;
	ELSE IF AST<40 AND AST>=20 THEN AST_S3=1;
	ELSE IF AST<20 THEN AST_S3=2;

*AST 결측 여부 확인 변수 만들기;
IF AST=. THEN AST_MISS=1;
	ELSE AST_MISS=0;

RUN;

*분할표 만들기;
PROC FREQ DATA=hong.df_new; 
TABLE AST_S3 * AST_MISS / NOROW NOCOL NOPERCENT; 
RUN;

 

결과

결측값 8개에 AST_S3의 값으로 2가 부여되어 있다. 이는 명백히 "ELSE IF AST<20 THEN AST_S3=2;" 코드에서 기인한 문제다. 즉, SAS는 AST의 결측치에 대해 "AST<20"가 옳다고 (TRUE) 본 것이다. 이를 해결하기 위해서는 코드를 다음과 같이 작성해야 한다. (두 가지 방법 모두 옳다.)

 

코드

*방법 1: "AST>=0"을 추가하기;
DATA hong.df_new;
SET hong.df;

*AST를 기준으로 셋으로 나누기;
IF AST>=40 THEN AST_S3=0;
	ELSE IF AST<40 AND AST>=20 THEN AST_S3=1;
	ELSE IF AST<20 AND AST>=0 THEN AST_S3=2;

RUN;

*방법 2: "AST^=."을 추가하기;
DATA hong.df_new;
SET hong.df;

*AST를 기준으로 셋으로 나누기;
IF AST>=40 THEN AST_S3=0;
	ELSE IF AST<40 AND AST>=20 THEN AST_S3=1;
	ELSE IF AST<20 AND AST^=. THEN AST_S3=2;

RUN;

방법 1은 "AST>=0"을 추가하여 결측치는 해당 조건을 만족하지 않게 조정한 것이다.

방법 2는 "AST^=."을 추가하였다.  "^="는 같지 않다는 뜻이므로, AST가 결측이 아니라는 뜻을 의미한다. 

 

각 방법에는 세 가지 조건이 존재한다. 방법 2를 기준으로 한다면 

조건 1: AST>=40

조건 2: AST<40 AND AST>=20

조건 3: AST<20 AND AST^=.

인데, 결측치는 세 조건 모두 부합하지 않았다. 따라서 결측치는 THEN 뒤로 넘어가 본 적이 없다. THEN 뒤에서는 AST_S3의 값을 배정받으므로 결측치는 AST_S3값을 배정받아본 적이 없는 것이다. 따라서 AST가 결측인 경우에는 AST_S3 또한 결측치가 된다. 

 

>, <, >=, <=등은 실제 코딩을 하다 보면 매우 입력하기 귀찮아지는데, 다음과 같은 영문 부호로 이를 대체할 수도 있다.

연산 부호 영문 부호
= EQ 같다
~=
^=
NE 같지 않다
> GT 크다
< LT 작다
>= GE 크거나 같다
<= LE 작거나 같다
^>
~>
NG 크지 않다
^<
~<
NL 작지 않다

 

 

 

MAX, MIN

최댓값을 구하는 MAX, 최솟값을 구하는 MIN 함수다. 간 기능 지표 (ALT, AST) 중 큰 것을 고른 LIVER_MAX변수와, 작은 것을 고른 LIVER_MIN변수를 새로 만든다고 하자. 그럼 코드는 다음과 같다.

DATA hong.df_new;
SET hong.df;

*최댓값;
LIVER_MAX=MAX(AST, ALT);
*최솟값;
LIVER_MIN=MIN(AST, ALT);
RUN;

LIVER_MAX=MAX(AST, ALT); : AST와 ALT 중 더 큰 값을 LIVER_MAX에 저장하라.
LIVER_MIN=MIN(AST, ALT); : AST와 ALT 중 더 작은 값을 LIVER_MIN에 저장하라.

 

여기에서는 결측치를 어떻게 처리할까?

AST, ALT 둘 중 하나가 결측치인 경우 MIN, MAX모두 결측치가 아닌 값을 반환한다. 

만약, AST, ALT 둘 다 결측치인 경우 MIN, MAX은 결측치를 반환한다.

 

 

상황: 전체 인구를 1) 과거 흡연자, 2) 비흡연자 및 현재 흡연자로 나누고 싶을 때

 이전 포스팅에서 이런 경우 조건문(IF)을 이용하여 나눌 수 있다고 하였다. 2022.10.06 - [통계 프로그램 사용 방법/SAS] - [SAS] 변수 계산 (논리 연산) - DATA, SET, IF, ELSE IF, ELSE, AND, OR

위 글에서도 간단하게 설명했지만 IN이라는 연산자를 이용하면 매우 빠르게 할 수 있다.

 

IN은 다음과 같이 사용할 수 있다. 

 

1) IN (0 2) : 0 혹은 2에 해당하는 경우

2) IN (0:2) : 0 이상 2 이하 정수에 해당하는 경우

 

IN을 NOT IN으로 바꾸면 "해당하지 않는 경우"로 바뀐다.

*결측치가 없음을 확인하기;
PROC MEANS DATA=hong.df NMISS;
VAR SMOK;
RUN;

DATA hong.df_new;
SET hong.df;

*과거 흡연자 // 현재 흡연자 + 비흡연자로 나누기;
IF SMOK IN (0 2) THEN SMOK_S2=0;
	ELSE SMOK_S2=1;

RUN;

IF SMOK IN (0 2) THEN SMOK_S2=0; : SMOK가 0 혹은 2인 경우 SMOK_S2에는 0을 부여한다.
ELSE SMOK_S2=1; : 그 외에는 SMOK_S2에 1을 부여한다.

 

SAS 변수 계산 (비교 연산) 정복 완료!

작성일: 2022.10.06.

최종 수정일: 2022.10.06.

이용 프로그램: SAS v9.4

운영체제: Windows 10

반응형
반응형

[SAS] 변수 계산 (논리 연산) - DATA, SET, IF, ELSE IF, ELSE, AND, OR

 조건에 따라 변수를 바꾸고 싶을 때가 있다. 예를 들어, 인구를 1) 음주 & 흡연자, 2) 음주 & 과거 흡연자, 3) 그 외로 나누고 싶을 수 있다. 이런 경우에 사용하는 논리 연산에 대해 알아보고자 한다. 내용은 다음과 같다.

 

1) 조건문 (IF, ELSE IF)

2) AND

3) OR

 

*실습용 데이터는 아래 링크를 클릭하면 다운로드할 수 있습니다.

2022.08.04 - [공지사항 및 소개] - 분석용 데이터 (update 22.10.06)

 

분석용 데이터 (update 22.10.06)

2022년 08월 29일 버전입니다. 변수는 계속하여 추가될 예정입니다. 다음 카테고리에 있는 글에서 이용된 데이터입니다. - 기술 통계 - 통계 프로그램 사용 방법 1) 엑셀 파일 2) CSV 파일 3) 코드북

medistat.tistory.com

 

시작하기 위해 라이브러리를 만들고, 파일을 불러온다.

라이브러리 만드는 방법: 2022.08.05 - [통계 프로그램 사용 방법/SAS] - [SAS] 라이브러리 만들기 - LIBNAME

파일 불러오는 방법: 2022.08.05 - [통계 프로그램 사용 방법/SAS] - [SAS] 데이터 불러오기 및 저장하기 - PROC IMPORT, PROC EXPORT

 

*라이브러리 지정하기;
LIBNAME hong "C:/Users/User/Documents/Tistory_blog";

*파일 불러오기;
PROC IMPORT
DATAFILE="C:\Users\user\Documents\Tistory_blog\Data.xlsx"
DBMS=EXCEL
OUT=hong.df
REPLACE;
RUN;

 

몇 가지 예시를 통해 논리 연산에 대해 배워보고자 한다.

 

상황 : 전체 인구를 현재 흡연자와 그 외(과거 흡연자와 비흡연자)로 나누려고 할 때

 데이터의 흡연 변수는 다음과 같이 코딩되어 있음을 코드북에서 확인할 수 있다.

SMOK 0 1 2
내용 비흡연자 과거 흡연자 현재 흡연자

 

우리는 SMOK_S2라는 변수를 새로 만들어 다음과 같이 코딩되기를 바란다.

SMOK_S2 0 1
내용 과거 흡연자와 비흡연자 현재 흡연자

 

즉, SMOK를 SMOK_S2로 바꿀 때, 다음과 같이 바뀌어야 한다.

  SMOK SMOK_S2
비흡연자 0 0
과거 흡연자 1 0
현재 흡연자 2 1

 

SMOK의 0과 1은 SMOK_S2에서 0이어야 하고, SMOK의 2는 SMOK_S2에서 1이어야 한다. 이를 실행하는 방법은 여러 가지가 있는데, 코드를 하나씩 살펴보면 다음과 같다. 변수를 바꿀 때 쓰는 DATA-SET구문에 대한 설명은 다음 링크를 확인하길 바란다. 2022.10.06 - [통계 프로그램 사용 방법/SAS] - [SAS] 변수 계산 (산술 연산) - DATA, SET

 

1) 방법 1 (가장 기초적)

DATA hong.df_new;
SET hong.df;

*현재 흡연자 // 과거 흡연자 + 비흡연자로 나누기 (1);
IF SMOK=0 THEN SMOK_S2=0;
	ELSE IF SMOK=1 THEN SMOK_S2=0;
	ELSE IF SMOK=2 THEN SMOK_S2=1;

RUN;

IF구문은 다음과 같은 구조를 띤다.

IF {조건1} THEN {실행1}                  :"조건 1"을 만족하면 "실행1"을 실시한다.

    ELSE IF {조건2} THEN {실행2}    :"조건 1"을 만족하지 않는 데이터 중 "조건 2"를 만족하면 "실행 2"를 실시한다.

    ...

    ELSE {마지막 실행}                     :"조건1", "조건 2", ... 를 만족하지 않는 데이터는 "마지막 실행"을 실시한다.

 

이를 적용하면 다음과 같이 해석할 수 있다.

 

IF SMOK=0 THEN SMOK_S2=0; : SMOK가 0이면 SMOK_S2는 0이다.
     ELSE IF SMOK=1 THEN SMOK_S2=0; : SMOK가 0이 아닌 사람 중 SMOK가 1인 사람의 SMOK_S2는 0이다.
     ELSE IF SMOK=2 THEN SMOK_S2=1; : SMOK가 0, 1이 아닌 사람 중 SMOK가 1인 사람의 SMOK_S2는 0이다.

 

여기에는 ELSE구문이 없으므로, 모든 조건에 부합하지 못한 데이터가 만약 있다면 그 사람의 SMOK_S2는 결측치로 대체된다.

2) 방법 2 

*결측치가 없음을 확인하기;
PROC MEANS DATA=hong.df NMISS;
VAR SMOK;
RUN;

DATA hong.df_new;
SET hong.df;

*현재 흡연자 // 과거 흡연자 + 비흡연자로 나누기 (2);
IF SMOK=0 THEN SMOK_S2=0;
	ELSE IF SMOK=1 THEN SMOK_S2=0;
	ELSE SMOK_S2=1;

RUN;

이번에는 결측치가 없음을 확인하고 "ELSE IF"가 아닌 "ELSE"를 사용할 것이다. PROC MEANS를 이용하여 결측치가 없음을 우선 확인하자. 이에 관한 내용은 다음 링크에서 확인할 수 있다. 2022.09.23 - [기술 통계/SAS] - [SAS] 기술 통계 (평균, 표준편차, 표준오차, 최댓값, 최솟값, 중위수, 분위수 등) - PROC UNIVARIATE, PROC MEANS

 

결측치가 없음을 확인했다면, 다음의 사고 과정은 매우 논리적이다.

 

1) 1000명 전원은 {비흡연자, 과거 흡연자, 현재 흡연자} 셋 중의 하나에 반드시 속한다.

2) 비흡연자에게 SMOK_S2는 0의 값을 부여하고, 과거 흡연자에게 SMOK_S2는 1의 값을 부여한다.

3) 아직 SMOK_S2값을 부여받지 못한 사람은 모두 현재 흡연자이므로 SMOK_S2는 1의 값을 부여한다.

 위의 3) 내용을 코드로 옮기면 "ELSE SMOK_S2=1"가 된다. 

 

만약 결측치가 있다면 흡연 정보를 모르는 사람 또한 SMOK_S2의 값은 1이 부여되어 현재 흡연자로 평가받기 때문에 결측치가 있을 때에는 이 코드를 사용하면 안 된다.

 

3) 방법 3

*결측치가 없음을 확인하기;
PROC MEANS DATA=hong.df NMISS;
VAR SMOK;
RUN;

DATA hong.df_new;
SET hong.df;

*현재 흡연자 // 과거 흡연자 + 비흡연자로 나누기 (3);
IF SMOK=0 OR SMOK=1 THEN SMOK_S2=0;
	ELSE SMOK_S2=1;

RUN;

OR 연산자를 사용하면 코드가 조금 더 간단해진다.

OR 연산자는 OR 앞뒤로 있는 조건 중 어떤 것이라도 만족하면 옳다고(TRUE)로 인식한다. 우리는 과거 흡연자, 비흡연자 모두 SMOK_S2에서는 0이라는 값을 부여할 것이므로 SMOK변수는 0이든 1이든 둘 중 하나이기만 하면 된다. 

IF SMOK=0 OR SMOK=1 THEN SMOK_S2=0;

그래서 SMOK=0, SMOK=1 중 하나라도 만족하면 SMOK_S2에는 0이라는 값을 부여한다는 위 코드를 사용하였다. 

 

4) 방법 4

다음 링크에서 비교 연산자에 대해 공부하고 온다면 다음과 같이 쓸 수 있음도 알 수 있다. 2022.10.06 - [통계 프로그램 사용 방법/SAS] - [SAS] 변수 계산 (비교 연산) - DATA, SET, GE, LE, NE, IN, MIN, MAX

*결측치가 없음을 확인하기;
PROC MEANS DATA=hong.df NMISS;
VAR SMOK;
RUN;

DATA hong.df_new;
SET hong.df;

*현재 흡연자 // 과거 흡연자 + 비흡연자로 나누기 (4);
IF SMOK<=1 THEN SMOK_S2=0;
	ELSE SMOK_S2=1;

RUN;

과거 흡연자와 비흡연자의 SMOK값은 각각 0,1이므로 "SMOK<=1"이라고 쓸 수도 있다.

만약 SMOK에 결측치가 있다면 비교 연산자중 일부는 결측치를 0으로 인식하므로, "SMOK<=1"을 만족한 것으로 본다. 따라서 결측치가 없음을 미리 확인해야 하며, 이에 관한 내용은 다음 링크에서 확인할 수 있다. 2022.10.06 - [통계 프로그램 사용 방법/SAS] - [SAS] 변수 계산 (비교 연산) - DATA, SET, GE, LE, NE, IN, MIN, MAX

 

5) 방법 5, 6

비교 연산자 중 IN을 사용하여 다음과 같이 작성할 수도 있다.

*결측치가 없음을 확인하기;
PROC MEANS DATA=hong.df NMISS;
VAR SMOK;
RUN;

DATA hong.df_new;
SET hong.df;

*현재 흡연자 // 과거 흡연자 + 비흡연자로 나누기 (5);
IF SMOK IN (0 1) THEN SMOK_S2=0;
	ELSE SMOK_S2=1;

RUN;

DATA hong.df_new;
SET hong.df;

*현재 흡연자 // 과거 흡연자 + 비흡연자로 나누기 (6);
IF SMOK IN (0:1) THEN SMOK_S2=0;
	ELSE SMOK_S2=1;

RUN;

방법 5의 IF SMOK IN (0 1) THEN SMOK_S2=0;

- SMOK가 0, 1인 데이터에게만 SMOK_S2의 값으로 0을 부여한다는 뜻이다.

방법 6의 IF SMOK IN (0:1) THEN SMOK_S2=0;

- SMOK가 0 이상 1 이하의 정수인 데이터에게만 SMOK_S2의 값으로 0을 부여한다는 뜻이다.

 

6) 방법 7

방법 6은 사실 "SMOK가 0 이상이면서 1 이하인 정수 데이터"에게 SMOK_S2의 값으로 0을 부여한 것이다. 이는 AND연산자를 사용한 것과 다름없다. AND 연산자는 AND 앞뒤로 있는 조건을 모두 만족해야 TRUE를 반환하는데, 이 경우 SMOK>=0 AND SMOK<=1 이라는 문구를 사용하면 되는 것이다.

*결측치가 없음을 확인하기;
PROC MEANS DATA=hong.df NMISS;
VAR SMOK;
RUN;

DATA hong.df_new;
SET hong.df;

*현재 흡연자 // 과거 흡연자 + 비흡연자로 나누기 (7);
IF SMOK>=0 AND SMOK<=1 THEN SMOK_S2=0;
	ELSE SMOK_S2=1;

RUN;

 

AND 연산자는 OR 연산자보다 우선하므로, 괄호를 적절히 치며 사용해야 한다. (사칙연산에서 곱셈이 덧셈보다 우선하는 것과 동일하다)

 

SAS 변수 계산 (논리 연산) 정복 완료!

작성일: 2022.10.06.

최종 수정일: 2022.11.03.

이용 프로그램: SAS v9.4

운영체제: Windows 10

 

반응형

+ Recent posts