R에서 데이터를 입력할 때 c() 를 사용하는데요, 일정한 반복이나 규칙을 따르는 데이터 입력이라면 함수 명령문을 이용하는게 단순 업무를 줄이는 방법이 되겠지요.

 

예전에 R의 장점이자 강점 중의 하나가 벡터 연산이 파워풀하다는 점이라고 했는데요,

 

아래의 rep(), seq() 함수를 곁들여서 벡터 연산에 활용하면 좋겠지요?!

 

 

 

 rep(), seq() 반복 데이터, 일정한 구조/순차 데이터 생성

 

 

(1) rep() : 일정한 데이터 반복

 

반복하고자 하는 4가지 형태별로 아래 예시를 들었습니다.

 


> ## "a"를 10번 반복

> rep("a", times = 10) [1] "a" "a" "a" "a" "a" "a" "a" "a" "a" "a" >

> ## "1"을 15번 반복

> rep(1, times = 15) [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 # 1 은 숫자형 그대로 임 >

> ## ("a" & "1") 을 5번 반복

> rep( c("a", 1), 5) [1] "a" "1" "a" "1" "a" "1" "a" "1" "a" "1" # "1"이 숫자형이 아니라 문자형으로 변환됨 >

> ## "a"를 먼저 5번 반복하고, "1"을 10번 반복

> rep( c("a", 1), c(5,10))
 [1] "a" "a" "a" "a" "a" "1" "1" "1" "1" "1" "1" "1" "1" "1" "1"

 

 




특정 범위의 정수 숫자를 각각 동일한 횟수로 반복하고자 한다면 rep(x:y, each=z) 함수를 사용하면 편합니다.

1~3까지의 정수를 10번씩 반복하는 예제는 아래와 같습니다.



> # repeat 1 at 10 times, 2 at 10 times, 3 at 10 times
> rep(1:3, each=10)
 [1] 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3

 




1행부터 20행까지 있는 데이터 프레임에서 1부터 5까지의 반복하는 숫자를 행 기준으로 반복하는 예제는 아래와 같습니다. dataframe$var <- rep(c(1:5), len = ncol(dataframe)) 처럼 할당하는 방법도 있고, cbind()를 사용하는 방법도 있는데요, 2가지 방법 모두 아래에 소개하였습니다. 진동, 주파수 처럼 일정한 주기성을 띠는 데이터를 분석하는 경우 분석 단위/구간 지정을 위해서 은근히 많이 사용하는 데이터 전처리 방법입니다.



> ## rep() exmaple
> x <- c(1:20)
> y <- rep(1, times = 20)
> z <- rep(c(1, 2), c(10, 10))
> xyz <- data.frame(cbind(x, y, z))
> xyz
    x y z
1   1 1 1
2   2 1 1
3   3 1 1
4   4 1 1
5   5 1 1
6   6 1 1
7   7 1 1
8   8 1 1
9   9 1 1
10 10 1 1
11 11 1 2
12 12 1 2
13 13 1 2
14 14 1 2
15 15 1 2
16 16 1 2
17 17 1 2
18 18 1 2
19 19 1 2
20 20 1 2
> 
> ## repeating c(a:b) from first row until last row : way 1
> xyz$seq_no_1 <- rep(c(1:5), len = nrow(xyz))
> xyz
    x y z seq_no_1
1   1 1 1        1
2   2 1 1        2
3   3 1 1        3
4   4 1 1        4
5   5 1 1        5
6   6 1 1        1
7   7 1 1        2
8   8 1 1        3
9   9 1 1        4
10 10 1 1        5
11 11 1 2        1
12 12 1 2        2
13 13 1 2        3
14 14 1 2        4
15 15 1 2        5
16 16 1 2        1
17 17 1 2        2
18 18 1 2        3
19 19 1 2        4
20 20 1 2        5
> 
> ## repeating c(a:b) from first row until last row : way 2
> seq_no_2 <- rep(c(1:5), len = nrow(xyz))
> xyz <- cbind(xyz, seq_no_2)
> xyz
    x y z seq_no_1 seq_no_2
1   1 1 1        1        1
2   2 1 1        2        2
3   3 1 1        3        3
4   4 1 1        4        4
5   5 1 1        5        5
6   6 1 1        1        1
7   7 1 1        2        2
8   8 1 1        3        3
9   9 1 1        4        4
10 10 1 1        5        5
11 11 1 2        1        1
12 12 1 2        2        2
13 13 1 2        3        3
14 14 1 2        4        4
15 15 1 2        5        5
16 16 1 2        1        1
17 17 1 2        2        2
18 18 1 2        3        3
19 19 1 2        4        4
20 20 1 2        5        5

 

 



(2) seq() : 일정한 구조/순차 데이터 생성

 

 아래 예시를 참고하세요.

 

 

> ## c()를 이용한 1부터 10까지 입력 (1 단위씩 커짐)
> c(1:10)
 [1]  1  2  3  4  5  6  7  8  9 10
> 
> ## seq()를 이용한 1부터 10까지 입력 (1 단위씩 커짐)
> seq(from=1, to=10)
 [1]  1  2  3  4  5  6  7  8  9 10
> 
> ## seq_len()을 이용한 1부터 10까지 입력 (1 단위씩 커짐)
> seq_len(10)
 [1]  1  2  3  4  5  6  7  8  9 10
> 
> ## seq()를 이용한 1~10까지의 숫자를 2단위씩 증가시키면서 입력
> seq( from = 1, to = 10, by=2 )  # from, to 는 제외해도 괜찮음
[1] 1 3 5 7 9
> 
> ## seq()를 이용한 1~10까지의 수를 5개의 숫자로 등간격으로 구성 (숫자는 5개, 구간은 4개)
> seq( 1, 10, length = 5 )  # from, to 는 제외해도 괜찮음
[1]  1.00  3.25  5.50  7.75 10.00
> 
# length.out : 개수 지정
> seq(from = 1, by = 2, length.out = 10)
 [1]  1  3  5  7  9 11 13 15 17 19

 

 

 

 

많은 도움이 되었기를 바랍니다. 

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡' 단추를 꾸욱 눌러주세요.^^

 

728x90
반응형
Posted by Rfriend
,

엑셀에서 외부 텍스트 데이터를 불러올 때 (1) ',', ':', ' ' 등의 구분자로 column을 구분하는 방식이 있고, (2) 일정한 간격, 고정된 폭으로 되어 있어서 대화상자에서 구분하는 폭/선을 마우스로 지정해주는 방식이 있습니다.

 

R에서 (1) 구분자가 들어있는 외부 텍스트 파일 불러오기는 지난번 포스팅에서 read.table(), read.csv() 함수를 소개했는데요,

 

이번 포스팅에서는 (2) 고정된 폭의 외부 텍스트 파일을 불러오는 함수 read.fwf() 함수에 대해 알아보겠습니다.

 

 

read.fwf() : 일정한 간격, 고정된 폭 구조의 외부데이터 불러오기

 

fwf 는 fixed width file 의 약자입니다.

아래 예제를 보면서 따라해보면 금방 사용법 알 수 있을 거예요.

 

 아래 형태처럼 1~2자리, 3~5자리, 6~8자리로 일정한 간격으로 되어있는 데이터를 불어와보도록 하겠습니다.


data_fwf.txt


 

 

read.fwf("디렉토리 경로",

       widths = c(간격 설정),

        col.names = c(변수명 설정))

 

> # fwf() 함수로 일정한 간격 외부 텍스트 데이터 불러오기

> data_fwf <- read.fwf("C:/Users/user/Documents/R/data_fwf.txt", # 경로 '/' 주의 + widths = c(2,3,3), + col.names = c("Var_1", "Var_2", "Var_3"))

 

 

불러온 데이터를 확인해 보면, col.names에서 할당한 변수명대로 해서 일정한 간격으로 구분되어 데이터가 들어가 있음을 알 수 있습니다.

 

> data_fwf
  Var_1 Var_2 Var_3
1    11   aaa   222
2    33   bbb   444
3    55   ccc   666

 

구분자를 안쓰는 경우 자칫 중간에 데이터가 꼬일 수 있으므로 read.fwf() 함수는 조심해서 써야 합니다. 기계에서 일정한 간격으로 흐트러짐 없이 쏟아져나오는 센서 데이터와 같이 일정한 간격, 고정된 구조의 데이터라고 확신이 있을 때만 사용하시기 바랍니다.

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡' 단추를 꾸욱 눌러주세요.^^

 

728x90
반응형
Posted by Rfriend
,
 

지난번 포스팅에서 데이터 프레임을 편리하게 사용할 때 사용할 수 있는 attach(), detach() 를 살펴보았습니다.

 

이번에는 주의할 점을 알아보도록 하겠습니다.  attach(), detach()가 편리한 기능이기는 합니다만, 아래의 3가지 경우 처럼 주의해서 사용하지 않으면 R 초보자의 경우 에러가 왜, 어디서 나는지 몰라서 애를 먹고, 심한 경우 R에 대해 '배우기 어려운 언어'라는 인식을 가지게 할 수 있는 함정이 바로 오늘 포스팅하는 내용이 되겠습니다. 

 

R 프로그래밍 하시는 분들, attach(), detach() 자주 쓰시는 분들은 반드시 숙지하시고 실수 하지 않기 위해, 혹은 실수 했더라도 콘솔에 나온 오류 메시지를 읽고서 뭐를 잘못했고 어떻게 대처해야 하는지를 알기 위해서 금번 포스팅을 읽어보시면 도움일 될거라 믿습니다.



 attach(), detach() 사용 시 주의할 점


(1) attach()후에 작업 공간 내 같은 이름, 다른 길이의 객체가 있으면 충돌(중복)
: 다음에 오류xy.coords(x, y, xlabel, ylabel, log) : 'x' and 'y' lengths differ

 

R에 내장되어 있는 'mtcars' 데이터 프레임을 가져다가 실습을 해보면서 설명드리겠습니다.

> ## attach(), detach() 사용할 때 주의할 점
> 
> str(mtcars) # mtcars 데이터 구조 확인
'data.frame':	32 obs. of  11 variables:
 $ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
 $ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
 $ disp: num  160 160 108 258 360 ...
 $ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
 $ drat: num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
 $ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
 $ qsec: num  16.5 17 18.6 19.4 17 ...
 $ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
 $ am  : num  1 1 1 0 0 0 0 0 0 0 ...
 $ gear: num  4 4 4 3 3 3 3 4 4 4 ...
 $ carb: num  4 4 1 1 2 1 4 2 2 4 ...
> head(mtcars) # 상위 6개 관측치 미리보기
                   mpg cyl disp  hp drat    wt  qsec vs am gear carb
Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1

 

 

attach()로 특정 데이터 프레임을 활성화 시킨 후에, 그 데이터 프레임에 있는 변수명과 같은 이름으로 벡터를 신규 생성하게 되면 R은 나중에 신규로 생성한 벡터 변수를 가져다가 작업을 하게 됩니다.  즉, 기존의 데이터 프레임의 변수가 새로운 수치로 변환이 되는게 아니라, 신규로 별도의 벡터가 따로 생기게 되다 보니 R이 동명이인을 두고 어찌할 바를 모르게 되는 겁니다. 이때 관측치 객수가 서로 다르다면 아래 예처럼 관측치 길이가 다르다고 에러 메시지가 뜨겠지요?

 

> attach(mtcars) # mtcars 데이터 프레임 활성화
> plot(hp, mpg) # 마력(hp: house power), 연비(mpg: mileage per gas) plot 그리기 OK
 

> # 마력, 연비 산포도 생성 성공

 

 
 
> 

> # mpg 라는 동일한 이름의 벡터를 생성 후 동일하게 산포도 명령 실행하면?
>
mpg <- c(20.0, 21.0, 19.2, 18.4, 19.9) # 동일한 이름의 mpg 벡터 신규 생성 > plot(mpg, hp) # 마력(hp), 연비(mpg) plot 그리기 에러발생 Error in xy.coords(x, y, xlabel, ylabel, log) : 'x' and 'y' lengths differ > > detach(mtcars)


서로 다른 의미(대상)의 벡터라면 이름을 다르게 해서 신규 생성하는게 답입니다. 그런데, R 프로그램 길게 짜다보면 인간인지라 실수로 중복 이름 벡터를 생성할수도 있고 하니, 간단한 명령어 실행할 때 에러를 원천 차단하려면,

 

(방법1)  '$'로 데이터 프레임을 지정(할당)해주고 변수를 불러오면 됩니다. 

 

> # 방법 1: '$' 로 데이터 프레임을 지정(할당)
> plot(mtcars$mpg, mtcars$hp)

 

 

 

 

 

 

(방법 2) detach() 후에, rm()으로 충돌(중복)되는 동일 이름 벡터 삭제 후 attach(), detach() 함수 활용

 

> # 방법 2: rm()으로 충돌(중복)되는 동일 이름 벡터 삭제 후 attach() 함수 활용

> detach(mtcars) # 활성화

> rm(mpg)  # 신규로 생성했었던 mpg 벡터 삭제

> attach(mtcars)

> plot(mpg, hp) # 다시 산점도 그리면 ok

 

 

 

 

 

> detach(mtcars)  # 활성화 해제

 

 

데이터 프레임을 attach()로 활성화 했다가 다 썼으면 끝에 꼭 detach()로 활성화 해제 잊지 말아야 겠죠.

 

 

(2) attach()후에 작업 공간 내 같은 이름, 다른 길이의 객체가 있으면 충돌(중복)
: The following object(s) are masked _by_ '.GlobalEnv' :

 

저는 R 초보일 때 분석하다 보면 이런 에러 메시지 많이 당했었고, 그때마다 이게 무슨 의미인지 몰라서 당황했었습니다. 아래 예제를 보면서 어떠할 때 이런 에러가 뜨는지 알아보겠습니다.

 

> # mtcars도 있는 동일한 이름의 hp 벡터 신규 생성 > hp <- c(120, 160, 110, 220)

 

# 우측 상단의 Global Environment 창에 hp 라는 벡터가 새로 생겼음을 확인할 수 있음

 

 

 

이런 상태에서 attach(mtcars)로 활성화(메모리에 임시로 데이터를 올리게 되면)를 하게 되면 mtcars 데이터 프레임에도 hp 라는 변수가 이미 들어있기 때문에 충돌이 나는 것입니다.

 

> attach(mtcars)
The following object is masked _by_ .GlobalEnv:

    hp

The following objects are masked from mtcars (pos = 3):

    am, carb, cyl, disp, drat, gear, hp, mpg, qsec, vs, wt
 
 
 

> hp # mtcars 데이터 프레임의 hp가 아니라 새로 생성한 벡터 hp가 호출됨 [1] 120 160 110 220

> > mtcars$hp # mtcars()$hp라고 해야지 mtcars 데이터 프레임 내 hp 벡터를 호출해옴 [1] 110 110 93 110 175 105 245 62 95 123 123 180 180 180 205 215 230 66 52 65 97 150 150 245 175 66 91 [28] 113 264 175 335 109

>

 

> rm(hp) # rm()으로 삭제한 이후에야 mtcars 데이터 프레임 내 hp를 호출하게 됨 > hp [1] 110 110 93 110 175 105 245 62 95 123 123 180 180 180 205 215 230 66 52 65 97 150 150 245 175 66 91 [28] 113 264 175 335 109


 이럴때는 rm()으로 중복되는 벡터를 삭제해주면 됩니다.

만약 생략해야 할 벡터가 많아서 일일이 rm() 명령어 치기가 귀찮다면 RStudio의 우측 상단에 붓 모양의 아이콘 클릭하면 전부 지워집니다. 전부 지워지니깐 조심해야 겠지만, 만약 전부 지워도 되는 거라면, 자꾸 에러가 나는데 뭐가 뭔지 잘 모르겠고 처음부터 다시 시작하고 싶다면 RStudio 우측 상단 붓 모양 아이콘으로 깔끔히 정리하고 R Script 짜놓은거 위에서 부터 순서대로 다시 해보면 실행 성공하는 경우 있습니다.

 

 

 

(3) attach()로 데이터 프레임을 메모리로 호출한 이후에 원본 데이터 프레임을 변경한 경우

 

attach()로 활성화 시켜서 메모리에 데이터가 올라온 상태에서 '$'로 혹은 transform() 함수로 데이터 객체를 변경하였다면 detach() 로 활성화를 해제시켰다가 다시 attach()로 활성화 시켜서 사용할 것.

> # cust_id, last_nm, age 세개의 벡터 생성
> cust_id <- c(1, 2, 3)
> last_nm <- c("Kim", "Lee", "Park")
> age <- c(20, 25, 29)
>

> # profile 이라는 데이터 프레임으로 cust_id, last_nm, age 세개 벡터 묶기 > profile <- data.frame(cust_id, last_nm, age) > profile cust_id last_nm age 1 1 Kim 20 2 2 Lee 25 3 3 Park 29

>

> # The following objects are masked _by_ .GlobalEnv: 안뜨게 하려면 삭제

> rm(cust_id, last_nm, age)  
>

>

> # attach()로 활성화

> attach(profile)

> age [1] 20 25 29 >

> # '$'로 profile 데이터 프레임을 지정하여 age 변수에 새로운 값 할당 (날씨 10살씩 더한 값)

> profile$age <- c(30, 35, 39) > profile # 새로운 age 값이 뜸 (원본 데이터는 변경되었음!!!!) cust_id last_nm age 1 1 Kim 30 2 2 Lee 35 3 3 Park 39

 

 

>

> # 그런데 attach()로 메모리에 불려들였던 'age'는 변하지 않은 이전 값임(주의 요망!!!!!)

> age [1] 20 25 29 >

> # 원본 데이터(변경 후)와 attach()로 메모리에 상주된 동일 변수 데이터가 값이 다르므로 주의요망

> # 해결 방법은 detach()로 메모리 상주(활성화) 해제 하고 attach()로 새로 활성화 시키면 됨

> detach(profile) > attach(profile) > age # 새로 변경한 값이 뜸 [1] 30 35 39 > detach(profile)

 

 

 

이번 포스팅 내용은 좀 어려울 것 같습니다. 저게 무슨 소리인가, 말인가 막걸리인가...그게 그 소리 같고... 헷갈리는 내용이지만 attach(), detach()는 아마 자주 사용하는 함수일터이니 제대로 알고 사용해야 에러를 피해갈 수 있겠지요?!

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡' 단추를 꾸욱 눌러주세요.^^

 

728x90
반응형
Posted by Rfriend
,

 

R 데이터 프레임 구조는 분석에 가장 많이 사용하는 구조의 데이터 셋입니다.

 

데이터 프레임의 변수를 활용하는 방법 3가지를 알아보도록 하겠습니다.

 

 

 

 R 데이터 프레임 활성화: with(), attach() & detach()

 

(1) 데이터 프레임 이름$변수명 : 입력할 거리가 몇 개 안되는 경우 적합

 

> ## 데이터 프레임 이름을 지정하지 않으면 R은 어디에서 변수를 가져와야 할지 알지 못함. 에러 발생

> mean(mpg) Error in mean(mpg) : object 'mpg' not found
>
> ## '데이터 프레임 이름$변수명' 형식으로 '$'를 이용해 객체 지정해주어야 R이 이해를 함
> mean(mtcars$mpg) [1] 20.09062 

>
> ## '0-1' 변환 해보기

> tf_0_1 <- (max(mtcars$mpg) - mtcars$mpg) / (max(mtcars$mpg) - min(mtcars$mpg)) > tf_0_1 [1] 0.54893617 0.54893617 0.47234043 0.53191489 0.64680851 0.67234043 0.83404255 0.40425532 [9] 0.47234043 0.62553191 0.68510638 0.74468085 0.70638298 0.79574468 1.00000000 1.00000000 [17] 0.81702128 0.06382979 0.14893617 0.00000000 0.52765957 0.78297872 0.79574468 0.87659574 [25] 0.62553191 0.28085106 0.33617021 0.14893617 0.77021277 0.60425532 0.80425532 0.53191489

* mtcars 는 R base 패키지에 내장된 데이터 프레임으로서, 자동차 32개 브랜드에 대해 11변수 값 조사해 놓은 자료.

str(mtcars) 해보면 데이터 구조, 변수명, 변수 개수, 관찰치 개수, 변수별 상위 데이터셋 미리보기 가능.

 

 

(2) with(데이터 프레임 이름, R 명령문) : R 명령문이 한 줄인 경우에만 사용 가능

 

위의 '$'는 R 명령어를 입력할 때마다 매번 '데이터 프레임 이름$변수명' 처럼 데이터 프레임 이름을 입력해주어야 하므로, 입력해야할 R 명령문이 많아지만 꽤 번거로운 방법이라고 하겠습니다. 모르면 손.발이 고생한다는 말이 딱 맞겠지요.

 

이럴 경우 손.발의 고생을 덜어주기에 유용한 함수가 with() 입니다. 위의 '0-1 변환'을 with()함수를 써서 해보겠습니다.

 

> tf_0_1_2 <- with(mtcars, (max(mpg) - mpg) / (max(mpg) - min(mpg)) )
> tf_0_1_2
 [1] 0.54893617 0.54893617 0.47234043 0.53191489 0.64680851 0.67234043 0.83404255 0.40425532
 [9] 0.47234043 0.62553191 0.68510638 0.74468085 0.70638298 0.79574468 1.00000000 1.00000000
[17] 0.81702128 0.06382979 0.14893617 0.00000000 0.52765957 0.78297872 0.79574468 0.87659574
[25] 0.62553191 0.28085106 0.33617021 0.14893617 0.77021277 0.60425532 0.80425532 0.53191489 

 

(1)번의 '$'를 사용한 노가다보다는 with()함수를 쓰니 훨씬 간결해지고 손도 덜 가지요?

다만, with()함수는 한 줄의 명령어만 가능하다보니 동일 데이터 프레임에 대해서 다수의 R 명령어를 써야 하는 상황이라면 attach(), detach() 함수를 사용해야 합니다.

 

 

(3) 활성화 시작 attach(데이터 프레임 이름), 끝 detach(데이터 프레임 이름): 다수의 R 명령문 입력 시 적합

 

공통적으로 계속 사용되는 대상 데이터 프레임을 지정(활성화 한다고 함)할 때는 attach(), 다른 데이터 프레임으로 바꾸고자 기존의 지정(활성화)된 데이터 프레임을 해제하고자 할때는 detach() 함수를 사용합니다.

 

> ## 데이터 프레임 활성화 attach()

> attach(mtcars) > tf_0_1_3 <- (max(mpg) - mpg) / (max(mpg) - min(mpg)) > tf_0_1_3 [1] 0.54893617 0.54893617 0.47234043 0.53191489 0.64680851 0.67234043 0.83404255 0.40425532 [9] 0.47234043 0.62553191 0.68510638 0.74468085 0.70638298 0.79574468 1.00000000 1.00000000 [17] 0.81702128 0.06382979 0.14893617 0.00000000 0.52765957 0.78297872 0.79574468 0.87659574 [25] 0.62553191 0.28085106 0.33617021 0.14893617 0.77021277 0.60425532 0.80425532 0.53191489 > > hist(mpg)

 

> summary(mpg) Min. 1st Qu. Median Mean 3rd Qu. Max. 10.40 15.42 19.20 20.09 22.80 33.90 >

> ## 데이터 프레임 활성화 해제 : detach() > detach(mtcars)

 

attach(데이터 프레임 이름 mtcars) 이후에 변수 변환도 하고, 히스토그램 그래프도 그리고, summary() 함수로 연비(mpg: mileage per gasolin)의 요약통계량을(최소값, Q1, 중앙값, 평균, Q3, 최대값) 구하는데 있어서 공통적으로 'mtcars' 데이터 프레임을 대상으로 해서 변수를 가져다가 R 함수가 실행되었습니다.

 

만약 '$'문을 사용했더라면 매번 데이터 프레임 이름을 계속 명기해주어야 하므로 노가다 좀 했겠지요? ^^

 

attach() 함수를 사용할 때 주의할 점이 있는데요, 그건 다음번 포스팅에서 다루도록 하겠습니다.

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡' 단추를 꾸욱 눌러주세요.^^

 

728x90
반응형
Posted by Rfriend
,

 

R 데이터 객체를 신규로 생성했거나, 외부에서 불러왔거나, 아니면 R 패키지에 내장되어 있는 데이터 셋을 활용한다고 했을 때 데이터 객체의 현황, 특성에 대해서 파악하는 것이 필요합니다.

 

이에 유용한 함수들을 알아보도록 하겠습니다.

 

 

 R 데이터 객체 탐색을 위한 함수 

 

R에 기본으로 내장되어 있는 'mtcars' 라는 데이터 프레임을 가지고 아래의 각 함수들의 예시를 들어보겠습니다.

'mtcars' 데이터는 1974 Motor Trend US magazine에서 자동차 디자인과 성능에 관해 추출한 11개의 변수로 구성된 데이터 프레임입니다.

 

> mtcars
                     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
Valiant             18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
Merc 240D           24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
Merc 230            22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
Merc 280            19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
Merc 280C           17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
Merc 450SLC         15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
Fiat 128            32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
Honda Civic         30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
Toyota Corolla      33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
Toyota Corona       21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
Dodge Challenger    15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
AMC Javelin         15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
Camaro Z28          13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
Pontiac Firebird    19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
Fiat X1-9           27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
Porsche 914-2       26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
Lotus Europa        30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
Ford Pantera L      15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
Ferrari Dino        19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
Maserati Bora       15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
Volvo 142E          21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2 

 

'mrcars' 라고 콘솔창에 치면 위의 박스 상자에 있는 것처럼 데이터 보기가 가능합니다. 이처럼 데이터 관찰치와 변수가 몇 개 안되면 콘솔창이나 아니면 environment 창에서 데이터셋을 눌러서 미리보기를 할 수 있겠읍니다만, 데이터 관찰치가 몇 백만이 되고 변수도 수천개가 넘는 데이터 객체라면 무리겠지요. 그래서 아래 함수들이 필요합니다.

 

 

(1) str(객체) : 데이터 구조, 변수 개수, 변수 명, 관찰치 개수, 관찰치의 미리보기

 

> str(mtcars)
'data.frame':	32 obs. of  11 variables:
 $ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
 $ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
 $ disp: num  160 160 108 258 360 ...
 $ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
 $ drat: num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
 $ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
 $ qsec: num  16.5 17 18.6 19.4 17 ...
 $ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
 $ am  : num  1 1 1 0 0 0 0 0 0 0 ...
 $ gear: num  4 4 4 3 3 3 3 4 4 4 ...
 $ carb: num  4 4 1 1 2 1 4 2 2 4 ... 

 

mtcars 가 '32개의 관측치', '11개의 변수'로 되어있는 '데이터 프레임'이고, 각 변수명과 변수들의 유형, 그리고 상위 10개의 관측치가 미리보기 형식으로 제시됩니다. 데이터 셋 탐색을 위해 제일 처음 해보면 좋을 유용한 함수입니다.

 

 

(2) head(), tail() : 상위 6개, 하위 6개 관측치 미리보기

 

> head(mtcars)
                   mpg cyl disp  hp drat    wt  qsec vs am gear carb
Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1


>
tail(mtcars) mpg cyl disp hp drat wt qsec vs am gear carb Porsche 914-2 26.0 4 120.3 91 4.43 2.140 16.7 0 1 5 2 Lotus Europa 30.4 4 95.1 113 3.77 1.513 16.9 1 1 5 2 Ford Pantera L 15.8 8 351.0 264 4.22 3.170 14.5 0 1 5 4 Ferrari Dino 19.7 6 145.0 175 3.62 2.770 15.5 0 1 5 6 Maserati Bora 15.0 8 301.0 335 3.54 3.570 14.6 0 1 5 8 Volvo 142E 21.4 4 121.0 109 4.11 2.780 18.6 1 1 4 2 

 

관측치가 수백만, 수천만 건인 경우는 상위 혹은 하위 몇개만 미리보기를 할 수 있으면 유용하겠지요.

 

 

(3) dim() : 데이터 객체의 차원

 

> dim(mtcars)
[1] 32 11 

 

str() 함수로 파악이 전부 가능한 정보인데요, 데이터 객체의 차원만 알고 싶거나 아니면 데이터 객체의 차원을 벡터로 해서 indexing해서 쓸일이 있을 때 이 함수를 사용하면 되겠지요.

 

 

(4) length() : 데이터 객체의 요소들의 개수

 

> length(mtcars) [1] 11

 

> length(mtcars$mpg)
[1] 32

 

첫번째 length(mtcars) 는 mtcars 데이터셋의 변수들의 개수를,

두번째 lenght(mtcars$mpg)는 mtcars의 데이터셋의 mpg라는 변수의 관측치의 개수를 나타냅니다.

(length()를 벡터에 사용하면 관측치의 개수를 나타냄)

목적에 맞게 골라서 사용하면 되겠습니다.

 

 

(5) names() : 데이터 객체 구성요소 이름

 

> names(mtcars)
 [1] "mpg"  "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"   "am"   "gear" "carb"

 

데이터 객체의 변수명을 알고 싶고, indexing해서 사용하고 싶으면 names() 함수를 사용하면 되겠습니다.

 

 

(6) class() : 데이터 객체 구성요소의 속성

 

> class(mtcars)
[1] "data.frame"
> sapply(mtcars, class)
      mpg       cyl      disp        hp      drat        wt      qsec        vs        am 
"numeric" "numeric" "numeric" "numeric" "numeric" "numeric" "numeric" "numeric" "numeric" 
     gear      carb 
"numeric" "numeric" 

 

첫번째의 class(mtcars)는 데이터 객체가 '데이터 프레임'임을 나타내고 있으며,

두번째 sapply(mtcars, class)는 'mtcars'라는 데이터 프레임의 모든 변수에다가 'class()라는 함수를 적용해라(sapply)고 했을 때의 결과로서, 11개의 각 변수별로 속성을 나타내고 있습니다.

(참고로, sapply()는 동일한 함수를 모두 적용하라는 함수입니다. 여기서는 class()라는 함수를 mtcars 내의 모든 변수에 공통으로 적용하라는 뜻입니다)

이 또한 목적에 맞게 골라서 사용하면 되겠습니다.

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡' 단추를 꾸욱 눌러주세요.^^

 

728x90
반응형
Posted by Rfriend
,

지난 포스팅에서

 

- R 데이터 객체를 외부 파일로 내보내서 저장하기 write.table()

 

- R 분석 결과를 외부 파일로 내보내서 저장하기 cat()

 

을 알아보았습니다.

 

 

 R 분석 결과 외부 파일로 저장하기 : capture.output()

 

이번 포스팅에서는 R 분석 결과 외부 파일로 저장하기 : capture.output()에 대해서 알아보도록 하겠습니다. 분석 결과를 외부로 내보내서 저장하는 cat()과 caputre.output()의 차이점은 cat()이 벡터를 다룬다면 capture.output()은 리스트를 다룬다는 점입니다.

 

아래 함수가

누구를 

어떤 데이터 구조를

무슨 일을 하는가? 

 wriite.table()

 데이터 객체

 데이터 프레임

(data frame)

 텍스트 파일로 외부 저장

 cat()  분석 결과  벡터 (vector)

 텍스트 파일로 외부 저장 

 capture.output()

 분석 결과  리스트 (list)   텍스트 파일로 외부 저장

 

 

capture.output() 함수를 아래 실습을 따라하면서 설명하도록 하겠습니다.

 

 

> ## 10명의 키, 몸무게로 데이터 프레임 만들기

> height <- c(175, 159, 166, 189, 171, 173, 179, 167, 182, 170)
> weight <- c(62, 55, 59, 75, 61, 64, 63, 65, 70, 60)
> d.f_h_w <- data.frame(height, weight)
> 

> ## 키와 몸무게 1차 선형 회귀모형 만들기

> lm_fit_h_w <- lm(weight ~ height, d.f_h_w)
> summary(lm_fit_h_w)
 

Call: lm(formula = weight ~ height, data = d.f_h_w) Residuals: Min 1Q Median 3Q Max -3.8614 -1.4780 -0.1812 1.1986 5.1787 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) -38.1534 18.2437 -2.091 0.069874 . height 0.5867 0.1053 5.573 0.000527 *** --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 Residual standard error: 2.727 on 8 degrees of freedom Multiple R-squared: 0.7952, Adjusted R-squared: 0.7696 F-statistic: 31.06 on 1 and 8 DF, p-value: 0.0005268

 

위에 만든 (1) 데이터 프레임과 (2) 회귀모형 적합 결과 summary(lm_fit_h_w) 를 텍스트 파일로 저장해보도록 하겠습니다.

 

  • "Dataset is as follows: " 문구 쓰고, lm_fit_h_w.txt 파일 생성

> cat( "Dataset is as follows; ",
+      "\n", 
+      "\n", 
+      file = "C:/Users/user/Documents/R/lm_fit_h_w.txt") 

 

 

 

  • lm_fit_h_w.txt 파일에 다가 lm_fit_h_w 데이터 프레임 데이터를 붙여서 저장하기 

> write.table(d.f_h_w, "C:/Users/user/Documents/R/lm_fit_h_w.txt", 
+             sep = ",", 
+             row.names = FALSE, 
+             quote = FALSE, 
+             append = TRUE)
Warning message:
In write.table(d.f_h_w, "C:/Users/user/Documents/R/lm_fit_h_w.txt",  :
  열의 이름들을 파일에 추가합니다 

 

 

 

  • "Summary of linear regression model is " 문구 삽입하기 

 

> cat( "Summary of linear regression model is ",
+      "\n", 
+      "\n", 
+      file = "C:/Users/user/Documents/R/lm_fit_h_w.txt", 
+      append = TRUE)

 

 

 

  • summary(lm_fit_h_w) 결과를 lm_fit_h_w.txt 파일에 붙여서 저장하기
    - cat() 함수를 쓰면 'list' 데이터 구조는 처리할 수 없다는 에러 메시지 발생

> cat( "\n", 
+      "\n", 
+      summary(lm_fit_h_w), 
+      file = "C:/Users/user/Documents/R/lm_fit_h_w.txt", 
+      append = TRUE)
Error in cat(list(...), file, sep, fill, labels, append) : 
  argument 3 (type 'list') cannot be handled by 'cat' 

 

 

               - 이때는 capture.output() 함수를 사용하면 됨

 

> capture.output(summary(lm_fit_h_w), 
+                file = "C:/Users/user/Documents/R/lm_fit_h_w.txt", 
+                append = TRUE) 

 

 

키와 몸무게의 1차 선형회귀모형의 summary() 결과가 텍스트 파일에 append 되어 저장되었음을 확인할 수 있습니다.

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡' 단추를 꾸욱 눌러주세요.^^

 

728x90
반응형
Posted by Rfriend
,

지난 포스팅에서 외부 파일을 R로 불러오는 함수에 대해서 알아봤다면, 이번 포스팅에서는 거꾸로 R에서 처리한 데이터 객체를 외부 파일(텍스트)로 저장하는 함수와 분석결과를 외부 파일로 저장하는 함수에 대해서 알아보겠습니다. 

 

(엑셀로 내보내는 것은 유용할 거 같아 시도해봤는데요, rJAVA가 안깔린다면서 에러가 나네요 -,-;)

 

 


 

 (1) 데이터 객체를 텍스트 파일로 저장: write.table()


지난 포스팅에서 외부 파일에서 R로 불러왔던 'dataset_1' 데이터 프레임을 이번에는 거꾸로 'cust_profile.txt'라는 이름으로 밖으로 내보내서 저장을 해보도록 하겠습니다. 

 

> ## 데이터 객체를 외부 텍스트 파일로 저장: write.table()

> write.table(dataset_1, "C:/Users/user/Documents/R/cust_profile.txt", 

+             sep = ",", 

+             row.names = FALSE, 

+             quote = FALSE, 

+             append = TRUE, 

+             na = "NA"

+             ) 

 

  • write.table( 데이터셋 이름, 저장할 경로/저장할 파일 이름...) 순서로 쓰되, 경로에 구분자가 '\'가 아니라 R에서는 '/' 이므로 주의 요망
  • sep = "," 또는 " " 또는 ":" 등 데이터 구분자 입력.  tab 구분자는 sep = "\t"
  • row.names = FALSE 행 이름(번호)가 생략됨. key 값이 별도로 있으면 생략하고, 혹시 key 값을 관리하고 싶은면 TRUE로 옵션 설정
  • quote = FALSE 면 변수 이름, 행 이름에 인용부호(" ") 생략. 구분자(sep)를 따로 지정하면 굳이 인용부호 없어도 무방
  • append = TRUE 이면 나중에 추가로 동일 파일 이름으로 write.table()함수가 실행될 경우 기존 파일에 덮어쓰기를 하지 않고 계속 이어 붙이기를 함. 덮어쓰기를 하면 기존 파일이 다 날아가버리고 마지막 덮어쓴 이후의 데이터만 남게되어 대략 난감한 상황 발생할 것이므로 append = FALSE 옵션은 조심. 
  • na = "NA" : 결측값이 있으면 "NA"로 표기. na = "." 이면 결측값을 마침표(.)로 표기.


[R 데이터 객체를 외부 텍스트 파일로 저장하기 전]

 

[R 데이터 객체를 외부 텍스트 파일로 저장하기 후 (cust_profile.txt 파일 신규 생성)]


 


 

 (2) 분석 결과를 외부 파일로 저장: cat()


[ 1~10 숫자형 벡터 x를 외부 텍스트 파일로 저장 ]

> ## 1~10 숫자형 벡터 x 생성

> x <- c(1:10)

> mean_x <- mean(x)

> sd_x <- sd(x)

> z_x <- ((x-mean_x)/sd_x)


> ## cat() 함수

> cat( "Data is as follows:", "\n", 

+      x, "\n", 

+      file = "C:/Users/user/Documents/R/data_x.txt", 

+      append = TRUE)


  • 큰따옴표(" ") 안에 텍스트는 그래도 출력됨
  • "\n"은 새로운 줄로 바꾸라는 뜻 (키보드 엔터 치라는 뜻)
  • 벡터 x 를 입력했더니 아래 처럼 벡터 x가 출력되었음. 벡터 연산도 가능. 
  • file = "" 파일 저장 경로 & 파일 이름 지정
  • append = TRUE 동일 경로 & 파일 이름으로 계속 이어 붙이기 하고 싶을 때 사용



[ x의 평균값을 기존 텍스트 파일에 이어 붙여서 저장 ]

> cat( "Mean of x is", mean_x, "\n", 

+      file = "C:/Users/user/Documents/R/data_x.txt", 

+      append = TRUE) 





[ x의 표준편차를 기존 텍스트 파일에 이어 붙여서 저장 ]

> cat( "Standard Deviation of x is", sd_x, "\n", 

+      "\n", 

+      "\n", 

+      "Z score of x is", z_x, "\n", 

+      file = "C:/Users/user/Documents/R/data_x.txt", 

+      append = TRUE) 





양이 적거나, 한번 하고 말일이면 그냥 console 창 가서 눈으로 분석결과 보고서 직접 타이핑하거나, 아니면 블럭 설정해서 복사 > 붙여넣기 하면 됩니다. 다만, 양이 아주 많거나, 아니면 다수 동일 반복작업이 필요한 경우는 cat() 함수로 프로그래밍을 하는게 노가다를 줄이고 정신 건강에도 좋겠지요?! 알아두면 유용한 함수입니다. 


console에 나타나는 모형 적합 결과를 외부 파일로 저장할 때 사용하는 capture.output()은 다음번 포스팅에 소개하도록 하겠습니다. 

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡'를 꾸욱 눌러주세요.^^


728x90
반응형
Posted by Rfriend
,

R에서 데이터를 c() 함수로 직접 입력하는 방법은 지난 포스팅에서 알아보았습니다. 

 

이 외에도

 

(1) edit() 함수를 이용해 엑셀 처럼 그리드 창에 직접 입력하는 방법과,

 

(2) 외부에서 txt나 csv, 엑셀 파일 등을 직접 불러오는 방법도 있습니다. 



(1) R 데이터 편집기 edit() 


엑셀 처럼 생긴 데이터 편집기 창을 사용하려면 edit() 함수를 이용하며, 데이터 프레임 구조로 저장됩니다. 

비교적 소규모의 데이터를 입력하기에는 써볼만 하겠지만, 대용량 데이터를 입력해야 하는 거라면 좀 무리겠지요? 


## 데이터 입력창 edit() 

> d.f <- data.frame()  # 데이터 프레임을 먼저 생성해 주고 나서, 

> d.f <- edit(d.f)  # 데이터 편집기 창 불러오기



edit() 함수로 데이터 편집기를 호출하면 아래와 같은 창이 뜹니다. 



'var1', 'var2', ....  부분을 클릭하면 '변수 편집기' 창이 팝업되며, '변수명'과 '유형(numeric, character)'을 편집할 수 있습니다. 




2. 외부 파일 데이터 불러오기  read.table() 


다수의 변수에 대해 다수의 관찰값이 2차원 형태로 구성된 데이터 파일을 불러오는데 read.table() 함수를 사용합니다. 


아래와 같은 데이터셋이 있습니다.

 


dataset_1.txt




> ## 외부 데이터셋 파일 불러오기

> dataset_1 <- read.table("C:/Users/user/Documents/R/dataset_1.txt", 

+                         header = TRUE,  # 변수명

+                         sep = ",",  # 구분자

+                         stringsAsFactor = FALSE, # 문자형 데이터를 요인으로 인식할지 여부

+                         na.strings = ""  # 결측값 표시

+                         ) 


  • '#' 은 R이 인식하지 않으므로 '#' 기호를 활용해 데이터셋에 대한 부가적인 설명을 덧붙여 놓을 수 있음

  • 파일 경로 입력할때는 Windows 탐색기 경로 구분자 '\' 가 아니라 '/' 로 반대 방향임을 주의 

  • 구분자 sep에는 콤마 ",", 빈칸 " ", ":", tap (sep = "\t") 등이 있음

  • stringsAsFactor = TRUE 하면 문자형 데이터를 요인(factor)으로 인식함. 요인으로 불러오는게 맞는지 아닌지 확인 필요

  • na.strings = "", ".", "NA" 등이 있음

  • 'csv' 파일은 read.csv() 함수를 사용. read.table() 함수와 다른 점은, read.csv()함수는 sep="," 옵션이 필요 없다는 점과 파일명 끝이 "dataset_name.cvs"로 끝난다는 점. csv 파일이 'comma separated values'의 약자로서 콤마로 구분자가 되어 있기 때문임. 


RStudio 의 우측 상단 'Environment' 메뉴에 보면 'dataset_1' 데이터 프레임이 생겼음을 확인할 수 있으며, 이를 클릭 시 왼쪽 상단에 'dataset_1' 이름으로 데이터셋 보기 화면이 열린다. 




엑셀, SAS, SPSS, 인터넷 홈페이지에서 불러오는 패키지가 있기는 합니다만 비추천하므로 포스팅은 생략합니다. 

엑셀은 sheet가 나뉘어져 있을 수도 있고 매크로 등의 함수가 걸려있을 수도 있어서 오류 여지가 있기에 엑셀 파일을 R로 불러오기 하는 것은 비추천합니다. SAS나 SPSS 파일을 불러오는 패키지도 버전 오류 여지가 있기에 비추천합니다. 홈페이지 URL도 언제 어떻게 바뀔지, 언제 없어질지 모르므로 비추천합니다. 

(엑셀 파일 불러오기 참고 ☞ http://rfriend.tistory.com/313 )


그냥 맘편하게, 확실하고 정확하게, txt나 csv 파일로 내려서 파일 불러오기 read.table() 함수 사용하시는걸 추천합니다. 

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡' 단추를 꾸욱 눌러주세요.^^

 

728x90
반응형
Posted by Rfriend
,


R에서 데이터의 일부분을 선택/선별하는 작업을 Indexing 한다고 합니다. 


R로 데이터 전처리, 분석을 하다보면 R Indexing을 부지기수로 사용하게 되니 R Indexing은 제대로 알고 넘어가야할 매우 중요한 부분입니다. 


특히, R에서는 벡터 Indexing 후 연산하는게 매우 큰 강점이고 유용한 기능이랍니다. 


R을 잘 몰랐을 때 남이 짜놓은 R 코드를 보면서 도무지 이해가 안되고 수수께끼 같았었는데요, 나중에 알고보니 Indexing을 사용한 것이었더라구요. Indexing, 모르면 어렵게 느껴져도 한번 알고 나면 참 쉬운 개념이고 파워풀한 기능이랍니다. 



 

 R Indexing (인덱싱), R 데이터 선택

 

Indexing은 대괄호 [ ] 를 사용합니다. 

바로 직전에 포스팅한 R 데이터 구조별로 Indexing 예를 차근차근 들어보도록 하겠습니다. 


(1) 벡터 (Vector) Indexing


벡터 Indexing 할 때 조건을 주는 방법이 한가지만 있는게 아니랍니다. 


> x <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

> ## 벡터 x의 첫번째 구성요소 Indexing
> x[1]

[1] 1
>
> ## 벡터 x의 세번째 구성요소 Indexing

> x[3]

[1] 3

> ## 벡터 x의 세번째~일곱번째 구성요소 Indexing

> x[c(3:7)]

[1] 3 4 5 6 7
>
> ## 벡터 x의 세번째, 다섯번째, 일곱번째 구성요소 Indexing

> x[c(3, 5, 7)]

[1] 3 5 7

> ## 벡터 x에서 TRUE 있는 위치의 구성요소 Indexing

> x[c(TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE)]

[1] 1 2 3 



(2) 행렬(Matrix) Indexing


행렬 Indexing은 대괄호 [i, j] 를 사용합니다. (i번째 행, j 번째 열을 뜻함)


> ## 1~12 숫자로 4열짜리 행렬 생성
> m1 <- matrix(1:12, nrow=4)

> m1

     [,1] [,2] [,3]

[1,]    1    5    9

[2,]    2    6   10

[3,]    3    7   11

[4,]    4    8   12


> ## m1 행렬에서 4번째 행, 2번째 열 구성요소 선택 (i, j indexing)

> m1[ 4, 2 ]

[1] 8

> ## m1 행렬에서 4번째 행 전체 구성요소 선택 (i indexing)

> m1[ 4, ]

[1]  4  8 12

> ## m1 행렬에서 2번째 열 전체 구성요소 선택 (j indexing)

> m1[ ,2 ]

[1] 5 6 7 8

> ## m1 행렬에서 3번째과 4번째 행의 2번째 열 구성요소 선택 (i, j indexing)

> m1[ c(3,4), 2 ]

[1] 7 8 



(3) 배열(Array) Indexing


배열은 동일한 유형의 2차원 이상의 데이터 구조로서, 행*열이 있는 바구니를 층층이 쌓아 놓은 모양이라고 했었지요. 층이 있다보니 Indexing할 때도 대괄호 [i, j, k] 로서 [행, 열, 층] indexing 위치를 표시합니다. 


> ## 1~24까지의 숫자를 가지고 2행*3열짜리 행렬을 4개 층으로 만들기
> a1 <- array(1:24, c(2,3,4))

> a1

, , 1


     [,1] [,2] [,3]

[1,]    1    3    5

[2,]    2    4    6


, , 2


     [,1] [,2] [,3]

[1,]    7    9   11

[2,]    8   10   12


, , 3


     [,1] [,2] [,3]

[1,]   13   15   17

[2,]   14   16   18


, , 4


     [,1] [,2] [,3]

[1,]   19   21   23

[2,]   20   22   24


> ## a1 배열의 2번째 행, 3번째 열, 4번째 층에 있는 구성요소 선택 (i, j, k indexing)

> a1[2,3,4]

[1] 24

> ## a1 배열의 1번째와 2번째 행, 3번째 열, 4번째 층에 있는 구성요소들 선택 (i, j, k indexing)

> a1[c(1,2), 3, 4]

[1] 23 24



(4) 데이터 프레임(Data Frame) Indexing


대괄호 [i, j] 로 표시, [i번째 행, j번째 열] indexing해오라는 뜻입니다. 

통계 분석 시 데이터 프레임 구조를 가장 많이 사용하다고 했으므로 데이터 프레임 Indexing도 많이 사용하겠지요? 

대골호를 하나만 쓰느냐 ([]), 두개를 쓰느냐 ([[]])에 따라서 indexing후의 데이터 구조(벡터 또는 데이터 프레임)가 달라지므로 주의를 요합니다. 벡터 구조로 indexing할 때 'dataset이름$변수이름' 형식으로 '$'를 쓰기도 합니다. 아래 예제를 보면 이해가 쉬울 것입니다. 


> ## dataframe 생성

> d1 <- c(1,2,3,4)

> d2 <- c("Kim", "Lee", "Choi", "Park")

> d3 <- data.frame(cust_id = d1, last_name = d2)

> d3

  cust_id last_name

1       1       Kim

2       2       Lee

3       3      Choi

4       4      Park


> ## d3 데이터 프레임에서 첫번째 행의 모든 구성요소를 선택 [i, ] => 데이터 프레임으로 출력됨

> d3[1, ]

  cust_id last_name

1       1       Kim

> ## d3 데이터 프레임에서 두번째 열의 모든 구성요소를 선택[ ,j] => 벡터로 출력됨

> d3[ ,2]

[1] Kim  Lee  Choi Park

Levels: Choi Kim Lee Park

> ## d3 데이터 프레임에서 첫번째 행, 두번째 열의 위치에 있는 구성요소 선택 [i,j] => 벡터로 출력됨

> d3[1,2]

[1] Kim

Levels: Choi Kim Lee Park

> ## d3 데이터 프레임에서 1번째 열(변수) 구성요소 선택 [j] => 데이터 프레임으로 출력됨

> d3[1]

  cust_id

1       1

2       2

3       3

4       4

> ## d3 데이터 프레임에서 "cust_id" 변수의 구성요소 선택 ["var_name"] => 데이터 프레임으로 출력됨

> d3["cust_id"]

  cust_id

1       1

2       2

3       3

4       4

> ## d3 데이터 프레임에서 1번째 열(변수) 구성요소 선택 [[j]] => 벡터로 출력됨

> d3[[1]]

[1] 1 2 3 4

> ## d3 데이터 프레임에서 "cust_id" 변수의 구성요소 선택 $ => 벡터로 출력됨

> d3$cust_id

[1] 1 2 3 4

> ## d3 데이터 프레임에서 3번째 & 4번째 행, 2번째 열의 구성요소 선택 [c(i,i), j] => 벡터로 출력됨

> d3[c(3,4),2]

[1] Choi Park

Levels: Choi Kim Lee Park

>  



(5) 리스트 (List) Indexing


리스트 Indexing은 겹대괄호 [[i]] 를 사용합니다. (i 번째 층을 선택)

통계 분석 결과가 리스트 데이터 구조로 많이 출력된다고 했는데요, 분석 결과 중에서 특정 통계량만 선택(indexing)해서 다른 분석의 input으로 넣는 경우에 indexing 이 유용하게 사용됩니다. 


> ## L1, L2, L3, L4 각 구조가 다른 4개의 객체로 L5라는 list (묶음 다발) 만들기

> L1 <- c(1, 2, 3, 4) # Vector

> L2 <- matrix(1:6, 3, byrow=TRUE) # Matrix

> L3 <- array(1:24, c(3,4,2)) # Array

> L4 <- data.frame(cust_id = c(1, 2, 3, 4), last_name = c("Kim", "Lee", "Choi", "Park")) # Dataframe

> L5 <- list(L1, L2, L3, L4) # List

> L5   # L5 리스트 출력

[[1]]

[1] 1 2 3 4


[[2]]

     [,1] [,2]

[1,]    1    2

[2,]    3    4

[3,]    5    6


[[3]]

, , 1


     [,1] [,2] [,3] [,4]

[1,]    1    4    7   10

[2,]    2    5    8   11

[3,]    3    6    9   12


, , 2


     [,1] [,2] [,3] [,4]

[1,]   13   16   19   22

[2,]   14   17   20   23

[3,]   15   18   21   24



[[4]]

  cust_id last_name

1       1       Kim

2       2       Lee

3       3      Choi

4       4      Park



> ## L5 리스트의 2번째 구성요소(2번째 층) 선택 [[i]]

> L5[[2]]

     [,1] [,2]

[1,]    1    2

[2,]    3    4

[3,]    5    6

> ## L5 리스트의 2번째 구성요소(2번째 층)의 3번째 행, 1번째 열의 구성요소 선택 [[i]][j, k]

> ## => 부연설명하자면, 일단 L5[[2]] 로 2번째 층 객체 선택 후 => 여기서 다시 [3, 1]로 3번째 행, 1번째 열 구성요소 선택한다고 생각하면 되겠음

> L5[[2]][3,1]

[1] 5 


여기까지 차분히 읽어오셨다면 R Indexing 의 머나먼 길을 완주하신겁니다. R의 훌륭한 무기 하나 득템하신 것을 축하합니다! 

 

※ 주의

 

R의 색인(indexing)이 '1'부터 시작하는 반면에,

Java, C, C++, Python 은 순차 자료형의 색인이 '0'부터 시작합니다.

R 말고 다른 언어 쓰시는 분들은 좀 헷갈릴 수 있는데요, 주의하시기 바랍니다.

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡' 단추를 꾸욱 눌러주세요.^^

 

728x90
반응형
Posted by Rfriend
,


SAS나 SPSS를 사용하다가 R을 처음 배우는 사용자라면 R에서 7개로 나누는 데이터 구조에 대해서 '이걸 왜 배우지? SAS나 SPSS는 이런거 모르고도 아무 문제 없이 데이터 처리, 분석 다 했었는데...'라는 의문과 함께, 'R 이거 배우기 어렵네...'라고 푸념할 수도 있겠습니다. 제가 그랬거든요. (SAS나 SPSS에서 주로 사용했던 데이터 구조가 R의 데이터 구조 중에서는 '데이터 프레임' or '행렬'이라고 하는 구조라고 생각하시면 됩니다. 전부다는 아니고 많은 경우....)


R의 데이터 구조별 특성에 대해서 정확하게 이해하지 않으면 나중에 데이터 처리, 분석 넘어갔을 때 자꾸 헷갈리고, 에러가 났을 때 에러 메시지가 무슨 의미인지 이해를 못할 가능성이 높습니다. 데이터 구조에 따라서 분석기법이 달라지게 되거든요. 라틴댄스로 치자면 빨리 '패턴' 배워서 멋지게 파트너와 춤추고 싶은데 선생님은 한달이고 두달이고 '스탭'만 연습시키는데요, 어찌보면 따분하고 답답한 '스탭' 기본기가 R로 치면 데이터 구조라고 생각하시면 되겠습니다. R의 기본이 되는 중요한 개념이므로, 그리고 나중에 이게 제대로 이해가 되고 R이 손에 익었다 싶을 때 다시 되돌아 보면 R에서 데이터 구조를 이렇게 나누어서 분석 기법을 달리 하는 것이 R의 차별화된 장점이자 특징이겠구나 하고 느끼게 되는 시점이 올겁니다. 


R 데이터 구조는 (1) 스칼라, (2) 벡터, (3) 요인, (4) 행렬, (5) 배열, (6) 데이터프레임, (7) 리스트의 7개로 나눌 수 있습니다. 하나씩 설명을 할텐데요, 처음에 잘 이해가 안가도 자꾸 R 사용하면서 다시 이번 포스팅 다시 돌아와서 한번씩 복습하시면 이해되는 날이 올거예요. (제가 Coursera로 강의 듣는데 R 데이터 구조라면서 강사가 막 영어로 뭐라 뭐라 하는데.... 뭔 소리인지 이해도 안되고, 이걸 왜 배우나 싶고, 짜증도 나고, 좌절도 되고...암튼 그랬는데요, 어느 순간 지나서 보니깐 다 이해를 하고 있더라고요. 한번 보고서 이해 안된다고 좌절하지 마시라는 뜻에서 자꾸 같은 소리 하고 있습니다. ^^;;;)



1. 스칼라 (Scala)


구성인자가 하나인 벡터를 말합니다. 


> # 스칼라 (Scala) : 구성인자가 1개인 벡터

> s1 <- c(1)

> s2 <- c("Kim") 



2. 벡터 (Vector)


벡터는 동일한 유형의 데이터가 구성인자가 1개 이상이면서 1차원으로 구성되어 있는 데이터 구조를 말합니다. 

(벡터 중에서 구성인자가 1개인 것을 '스칼라'라고 합니다)


> # Vector

> v1 <- c(1, 2, 3)                   # 숫자형 벡터

> v2 <- c("Kim", "Lee", "Choi")    # 문자형 벡터

> v3 <- c(TRUE, TRUE, FALSE)   # 논리형 벡터



3. 요인 (Factor) 


범주형(명목형 또는 순서형)의 데이터 구조를 요인(Factor)라고 합니다. 통계 분석 할 때 소위 '~~별' 분석을 할 때 쓰는게 요인이므로 굉장히 많이 사용됩니다. 나중에 분석을 하다보면 (1) '요인'으로 데이터를 변환해야 하는 경우도 생기고, (2) 반대로 '요인'이 아니어야 하는데 '요인'으로 데이터가 입력이 되어있어서 에러가 발생하는 경우도 생기곤 합니다. '요인'이 뭔지, 뭐에 쓰는 것인지 모르면 두 가지 경우 상황 파악을 못해서 곤혹스럽겠지요? 

요인이 가질 수 있는 값들을 '수준(level)'이라고 합니다. RDBMS에서의 '코드값'이라고 이해하면 되겠습니다. 수준(level)은 명목형은 상관없지만, 순서형의 경우 순서(order)를 부여할 수 있습니다. 분석 결과가 순서대로 범주화 되서 나와야 보기에 좋겠지요?


> # (1) 문자형 데이터를 그냥 입력하면, 따옴표가 있는 문자형 벡터가 생성

> f1 <- c("Middle", "Low", "High")

> f1

[1] "Middle" "Low"    "High"  

>

> # (2) factor()함수를 이용해서 문자형 벡터를 요인(factor)로 변환

> # 단, 순서를 지정 안해주면 알파벳 순서로 수준(level)이 자동으로 지정됨

> f2 <- factor(f1)

> f2

[1] Middle Low    High  

Levels: High Low Middle

>

> # (3) 수준(level)에 순서를 부여하려면 'order=TRUE' 옵션 설정, level=c("") 에 순서대로 입력

> f3 <- factor(f2, order = TRUE, level = c("Low", "Middle", "High"))

> f3

[1] Middle Low    High  

Levels: Low < Middle < High 



4. 행렬 (Matrix) 


행렬은 동일한 유형의 2차원 데이터 구조를 말합니다. (쉽게 말해 m x n 형태의 표 형태의 데이터)

참고로, 벡터는 동일한 유형의 1차원 데이터 구조라고 했지요. (쉽게 말해, 가로로 늘어선 한 줄 데이터)


행렬은 matrix() 라는 함수를 사용합니다. 

최적화(optimization) 할 때 제약조건을 행렬로 입력합니다. 공학에서 행렬 많이 사용합니다. 


> # 1~12까지의 숫자를 행(row)의 수가 4개인 행렬로 만들어라

> m1 <- matrix(1:12, nrow=4)

> m1

     [,1] [,2] [,3]

[1,]    1    5    9

[2,]    2    6   10

[3,]    3    7   11

[4,]    4    8   12

> # 1~12까지의 숫자를 행(row)의 수가 4개이고 행렬로 만드는데, 행 기준(byrow=TRUE)으로 채워나가라

> m2 <- matrix(1:12, nrow=4, byrow=TRUE)

> m2

     [,1] [,2] [,3]

[1,]    1    2    3

[2,]    4    5    6

[3,]    7    8    9

[4,]   10   11   12

>  



5. 배열 (Array) 


배열(Array)은 동일한 유형의 데이터가 2차원 이상으로 구성된 구조를 말합니다. 

참고로, 행렬은 동일한 유형의 2차원 데이터 구조라고 했지요. 따라서 배열은 쉽게 말해 행렬이라는 방을 층 층이 쌓아놓은 아파트라고 생각하시면 되겠습니다. 


> # 1~24까지의 숫자를 '2 x 3 행렬'로 해서 '4층' 짜리의 데이터 구조를 만들어라

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

> a1

, , 1


     [,1] [,2] [,3]

[1,]    1    3    5

[2,]    2    4    6


, , 2


     [,1] [,2] [,3]

[1,]    7    9   11

[2,]    8   10   12


, , 3


     [,1] [,2] [,3]

[1,]   13   15   17

[2,]   14   16   18


, , 4


     [,1] [,2] [,3]

[1,]   19   21   23

[2,]   20   22   24 



> # 1~24까지의 숫자를 '3 x 4' 행렬로 해서 '2층'짜리의 데이터 구조를 만들어라

> a2 <- array(1:23, c(3,4,2))

> a2

, , 1


     [,1] [,2] [,3] [,4]

[1,]    1    4    7   10

[2,]    2    5    8   11

[3,]    3    6    9   12


, , 2


     [,1] [,2] [,3] [,4]

[1,]   13   16   19   22

[2,]   14   17   20   23

[3,]   15   18   21    1





6. 데이터 프레임 (Data Frame) 


데이터 프레임데이터 유형에 상관없이 2차원 형태의 데이터 구조를 말합니다. 

참고로, 행렬동일한 유형의 데이터가 2차원 형태로 구성되었다고 했지요. 

통계, 마이닝 분석할 때 데이터 프레임을 주로 사용합니다. 


> # 다른 유형의 벡터 생성

> d1 <- c(1,2,3,4)

> d2 <- c("Kim", "Lee", "Choi", "Park")

> # 데이터 프레임으로 묶기 : data.frame() 함수 사용

> d3 <- data.frame(cust_id = d1, last_name = d2)  # 변수명 부여

> d3

  cust_id last_name

1       1       Kim

2       2       Lee

3       3      Choi

4       4      Park 



7. 리스트 (List) 


리스트는 벡터, 행렬, 배열, 데이터 프레임 등과 같은 서로 다른 구조의 데이터를 모두 묶은 객체를 말합니다. 

참고로, 리스트 말고 나머지들은 서로 다른 구조의 데이터 끼리는 묶어 놓지 않았고 따로 따로 였지요. 

R에서는 통계 분석 결과가 보통 리스트 구조로 제시되고, 필요로 하는 통계량이 있으면 indexing해서 뽑아서 쓰기도 합니다. 

서로 다른 구조의 다수의 데이터 객체를 개별로 따로 따로 관리하는 것보다는, 이것들을 리스트라는 한 바구니에 가지런히 정리해서 모아놓으면 관리하기에 편하겠지요? 


> # Vector(L1), Matrix(L2), Array(L3), Data Frame(L4)를 만들어서, 하나의 List(L5)로 묶어라

> L1 <- c(1, 2, 3, 4) # Vector

> L2 <- matrix(1:6, 3, byrow=TRUE) # Matrix

> L3 <- array(1:24, c(3,4,2)) # Array

> L4 <- data.frame(cust_id = c(1, 2, 3, 4), last_name = c("Kim", "Lee", "Choi", "Park")) # Data Frame

> L5 <- list(L1, L2, L3, L4) # List

>

> # [[1]]는 Vector(L1), [[2]]는 Matrix(L2), [[3]]는 Array(L3), [[4]]는 Data Frame(L4)가 묶인 것임

> L5

[[1]]

[1] 1 2 3 4


[[2]]

     [,1] [,2]

[1,]    1    2

[2,]    3    4

[3,]    5    6


[[3]]

, , 1


     [,1] [,2] [,3] [,4]

[1,]    1    4    7   10

[2,]    2    5    8   11

[3,]    3    6    9   12


, , 2


     [,1] [,2] [,3] [,4]

[1,]   13   16   19   22

[2,]   14   17   20   23

[3,]   15   18   21   24



[[4]]

  cust_id last_name

1       1       Kim

2       2       Lee

3       3      Choi

4       4      Park

 


지금까지 살펴본 R의 데이터 구조를 도식화하면 아래와 같습니다. 뭐가 뭐의 부분집한인지, 각 데이터 구조를 구분하는 기준은 무엇인지 유심히 다시 한번 살펴보기 정리해보면 좋겠습니다. 



[ R 데이터 구조 (Data Structure in R) ]



많은 도움 되었기를 바랍니다.

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡' 단추를 꾸욱 눌러주세요.^^


728x90
반응형
Posted by Rfriend
,