R의 장점이자 특징 중의 하나가 벡터 연산이 가능해서 프로그램을 깔끔하게 짤 수 있고 연산처리 속도가 빠르다는 점, Indexing을 활용하면 필요한 벡터 객체만 가져다가 다시 프로그램의 input으로 사용할 수 있다는 점 등에 대해 이전에 소개해준 적이 있는데요,

 

그럼 이번에는 벡터 끼리 혹은 벡터와 스칼라 간에 비교할 때 쓰는 비교/논리 연산자에 대해서 알아보도록 하겠습니다.

 

 

 

벡터의 비교/논리 연산자 

 

 

-- 비교 연산자 --

 

(1) ~ 보다 크다 :  >

 

aa, bb 라는 벡터와 cc 라는 스칼라를 만들어서 비교/논리 연산자를 실습해 보겠습니다.

 

> aa <- c(1, 2, 3, 4, 5, 6, 7) # 벡터
> bb <- c(7, 6, 5, 4, 3, 2, 1) # 벡터
> cc <- c(4) # 스칼라
> 
> aa > bb
[1] FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE
> aa > cc
[1] FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE

 

'>' 연산자를 실행하면 'TRUE', 'FALSE'와 같은 논리형 벡터가 아래에 출력됩니다.

 

'aa' 벡터는 구성요소가 7개인 반면에, 'cc' 스칼라는 구성요소가 1개 밖에 없는데도 비교 연산이 되었습니다. 이처럼 서로 구성요소의 개수가 다르면 스칼라가 R 내부적으로 7번 반복이 되어서 순환연산이 실행되었습니다.  벡터끼리 연산할 때도 서로 개수가 다르면 개수가 작은 쪽이 순환연산이 이루어져서 서로 짝을 맞추어서 연산이 실행됩니다.

 

 

(2) ~ 보다 크거나 같다 : >=

 

> aa >= bb
[1] FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE
> aa >= cc
[1] FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE

 

 

(3) ~ 보다 작다 : <

 

> aa < bb
[1]  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE
> aa < cc
[1]  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE 

 

 

(4) ~ 보다 작거나 같다 : <=

 

> aa <= bb
[1]  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE
> aa <= cc
[1]  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE
> aa =< cc
Error: unexpected '<' in "aa =<"

 

세번째 명령어에 보면 부호의 순서가 '=<' 처럼 '~보다 같거나 작다'의 순서로 했더니 에러가 났습니다. '<=' 처럼 '~보다 작거나 같다'의 순서로 부호 사용하기 바랍니다.

 

 

(5) 서로 같다 : ==

 

> aa == bb
[1] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
> aa == cc
[1] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE

 

R에서 객체를 할당할 때 '<-' 또는 '=' 를 사용하는데요, 비교 연산자의 '==' 과 헷갈리지 않도록 합니다.

 

 

(6) 서로 같지 않다 : !=

 

> aa != bb
[1]  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE
> aa != cc
[1]  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE
> aa =! cc
> 

 

 

서로 같지 않다도 부호의 순서를 '!=' 로 해야지만 논리형 벡터가 결과 값으로 나옵니다. 세번째 줄처럼 '=!'로 하면 논리형 벡터 결과가 안나오니 순서 주의하세요.

 

 

 

-- 논리 연산자 --

 

(7) 동시에 조건 만족 (aa AND bb)  : aa & bb

 

> aa <- c(1, 2, 3, 4, 5, 6, 7) # 벡터 > bb <- c(7, 6, 5, 4, 3, 2, 1) # 벡터 > cc <- c(4) # 스칼라

>

> aa > 3 & aa < 6
[1] FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE
> aa >= 3 & aa <= 6
[1] FALSE FALSE  TRUE  TRUE  TRUE  TRUE FALSE

 

 

 

 

(8) 또는 조건 만족 (aa OR bb) : aa | bb

 

> aa < 3 | aa > 6
[1]  TRUE  TRUE FALSE FALSE FALSE FALSE  TRUE
> aa <= 3 | aa >= 6
[1]  TRUE  TRUE  TRUE FALSE FALSE  TRUE  TRUE 

 

 

-- 논리 연산자에 대한 추가 연산 --

 

(9) 조건 만족하는 논리형 벡터에 대한 합계, 평균 : sum(), mean()

 

> sum(aa > 3 & aa < 6)
[1] 2
> sum(aa < 3 | aa > 6)
[1] 3
> mean(aa > 3 & aa < 6)
[1] 0.2857143
> mean(aa < 3 | aa > 6)
[1] 0.4285714

 

R은 'TRUE'는 '1'로, 'FALSE'는 '0'으로 내부적으로 인식합니다. 따라서 sum()이나 mean() 과 같은 숫자형 벡터에 대한 통계 함수를 사용할 수가 있습니다.

 

 

(10) 비교/논리 연산 결과에 대해 하나라도 (any) 혹은 전부(all) TRUE 가 있는지 여부 확인 : any(), all()

 

> any(aa > 3 & aa < 6)
[1] TRUE
> all(aa > 3 & aa < 6)
[1] FALSE
> any(aa > 8)
[1] FALSE
> any(aa == 1)
[1] TRUE
> all(aa == 1)
[1] FALSE

 

 

위의 (1) ~ (9)번까지의 예들이 1~7까지의 혹은 7~1까지의 몇 개 안되는 구성요소를 가지고 예를 들다보니 눈으로 보면 TRUE가 뭐고 몇 개인지 바로 알 수 있지만요, 실제 분석할 때는 많은 경우 관측치 수가 수 만개, 수 백만개, 수 천만개가 되는 경우가 많습니다. 그때 일일이 육안으로 TRUE, FALSE를 확인한다는 것은 사실상 불가능합니다. 따라서 비교/논리 연산 결과에 대해 sum(), mean(), any(), all() 등과 같은 함수를 적절히 활용해서 즉시 데이터 셋에 대한 상황 파악(탐색)을 하는 것이 필요합니다.

 

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

 

Posted by R Friend R_Friend

댓글을 달아 주세요

  1. gongju5908 2018.10.05 14:35  댓글주소  수정/삭제  댓글쓰기

    안녕하세요. 항상 도움이 되고 있습니다. 감사합니다.
    질문을 드리고 싶은데요^^
    1번 : temp1=temp[which(temp$HCHK_APOP_PMH_YN!="1" & temp$HCHK_HDISE_PMH_YN !="1"),]
    2번 : JJ1=JJ[which(!JJ$HCHK_APOP_PMH_YN %in% c("1") & !JJ$HCHK_HDISE_PMH_YN %in% c("1")),]

    숫자가 차이가 있어요. 혹시 1번 2번 차이점이 무엇인지 알고 계신가요????

통계는 크게 표본의 (a) 도수 분포와 중심화 경향, 그리고 퍼짐 정도를 측정하여 집단의 특성에 대해서 기술하는 기술통계(descriptive statistics)와, (b) 기술통계량을 가지고 모집단의 parameter 값 (모평균, 모분산 등)을 추정하고 가설을 검증하는 추정통계(inferential statistics)로 구분할 수 있습니다.

 

이번 포스팅에서는 R에서 벡터를 대상으로 사용할 수 있는 기술 통계 관련 함수에 대해서 알아보겠습니다.

 

R 기술통계 함수

 

-- 분포 및 중심화 경향 --

 

(1) 평균 : mean(x)

 

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

 

 

(2) 중앙값 : median(x)

 

> x <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
> median(x)
[1] 5.5
> y <- c(1, 2, 3, 4, 5, 6, 7, 8, 9)
> median(y)
[1] 5

 

벡터 x가 홀수개이면 정 가운데 값을 중앙값을 가져오지만, 위의 case와 같이 x가 짝수개 이면 정가운데의 양쪽 두개의 값을 가져다가 평균을 내서 중앙값을 계산합니다.

 

 

(3) 최소값 : min(x)

 

> min(x)
[1] 1
> min(y)
[1] 1 

 

 

which.min(my_vec) 은 최소값이 있는 위치의 index 를 반환합니다. NA가 포함되어 있는 vector의 경우 min(my_vec) 이 NA를 반환한데 반해서 (NA에 대한 전처리 필요), my_vec[wich.min(my_vec)] 처럼 최소값을 ndexing을 해오면 '-12'를 반환했습니다.

 

 

> my_vec <- c(-5, 3, 10, 3, -12, NA)
> my_vec
[1]  -5   3  10   3 -12  NA
> 
> min(my_vec)
[1] NA
> 
> which.min(my_vec) # index of min value in 'my_vec' vector
[1] 5
> 
> my_vec[which.min(my_vec)]
[1] -12

 

 

 

 

(4) 최대값 : max(x)

 

> max(x)
[1] 10
> max(y) 

 

> my_vec <- c(-5, 3, 10, 3, -12, NA)
> my_vec
[1]  -5   3  10   3 -12  NA
> 
> max(my_vec)
[1] NA
> 
> which.max(my_vec) # index of max value in 'my_vec' vector
[1] 3
> 
> my_vec[which.max(my_vec)]
[1] 10 

 

 

 

(5) 범위 : range(x)

 

> range(x)
[1]  1 10
> range(y)
[1] 1 9 

 

 

(6) IQR(Inter-Quartile Range) : IQR(x)

 

> IQR(x)
[1] 4.5
> IQR(y)
[1] 4 

 

 

(7) 중심화 경향 및 분포 요약 : summary(x)

 

> summary(x)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00    3.25    5.50    5.50    7.75   10.00 

 

숫자형 벡터의 경우 summary() 함수가 위의 1번에서 6번까지 함수를 한번에 처리할 수 있는 유용한 함수가 되겠습니다.

 

 

-- 퍼짐 정도 --

 

(8) 분산 : var(x)

 

> var(x)
[1] 9.166667
> var(y)
[1] 7.5 

 

 

(9) 표준편차 : sd(x)

 

> sd(x); sd(y)
[1] 3.02765
[1] 2.738613 

 

참고) 세미콜론 ';' 을 사용하면 같은 줄에 R 명령어를 연속으로 해서 쓸 수 있습니다

 

 

-- 확률분포의 비대칭 정도 --

 

(10) 왜도

 

> install.packages("fBasics") # 왜도, 첨도 분석 가능한 package 설치 > library(fBasics) # package 호출 > hist(mtcars$mpg)

 

 

 

 

 

 

> skewness(mtcars$mpg) [1] 0.610655 attr(,"method") [1] "moment"

 

 

R에 왜도와 첨도를 위한 함수가 내장되어 있지 않기 때문에 별도 패키지(fBasics)를 설치해야 합니다.

자동차 정보가 들어있는 mtcars 데이터 프레임의 연비에 대해서 히스토그램을 그려보니 평균보다 왼쪽으로 치우쳐 있고 오른쪽으로 꼬리가 긴 분포를 띠고 있네요. 그러면 왜도(skewness) 가 '0'보다 크게 나타납니다. (공식이 평균에서 관측치를 뺀 값을 3제곱 하기 때문이예요) 위 예에서는 왜도가 0.61로 '0'보다 크게 나왔지요. 정규분포의 평균과 일치하면 왜도는 '0'이 되고, 반대로 평균보다 오른쪽으로 값이 치우쳐 있고 왼쪽으로 꼬리가 길면 왜도는 '0'보다 작은 값이 나옵니다.

 

 

(11) 첨도

 

> kurtosis(mtcars$mpg)
[1] -0.372766
attr(,"method")
[1] "excess"

 

관측값이 정규분포보다 뾰쪽한가 아닌가를 가늠하는 쳑도가 첨도입니다. '3'보다 크면 정규분포보다 더 뾰족한 모양이고, '3'보다 작으면 정규분포보다 덜 뾰족한 모양이라고 해석하면 되겠습니다. (패키지에 따라서는 '3'을 빼서 '0'으로 표준화해서 값을 제시하기도 합니다)

 

 

-- 기타 함수 --

 

(12) 합 : sum(x)

 

> sum(x)
[1] 55
> sum(y)
[1] 45

 

 

(13) n차 차분 : diff(x, lag=n)

 

> diff(x, lag=1)
[1] 1 1 1 1 1 1 1 1 1
> diff(x, lag=2)
[1] 2 2 2 2 2 2 2 2
> diff(x, lag=3)
[1] 3 3 3 3 3 3 3 

 

관측값에서 직전 관측값을 뺀 차분을 구하는 함수입니다. 시계열분석할 때 정상화하기 위해서 차분을 이용하는데요, 시차(lag)를 분석 목적에 따라 또 데이터 특성에 따라서 입력해주면 됩니다. 디폴트는 lag=1 이 되겠습니다.

 

 

(14) 길이, 관측값 개수 : length()

 

> # 벡터에 length() 사용 시
> length(x)
[1] 10
> length(y)
[1] 9 
> 

> # 데이터 프레임에 length()사용 시

> length(mtcars)
[1] 11
> 

> # 데이터 프레임의 특정 변수에 length($) 사용 시

> length(mtcars$mpg)
[1] 32

 

벡터에서 length()는 관측값 개수를 계산해서 보여줍니다.

데이터 프레임에서는 column 개수를 나타내주고요, 데이터 프레임의 특정 변수를 지정하면 그 특정 변수의 관측값의 개수를 세서 보여줍니다.

 

 

(15) 순위 : rank()

 

> rank(x) [1] 1 2 3 4 5 6 7 8 9 10 >
>
rank(-x) [1] 10 9 8 7 6 5 4 3 2 1 >

> mtcars$mpg
 [1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 15.2 10.4 10.4 14.7 32.4 30.4 33.9 21.5 15.5
[23] 15.2 13.3 19.2 27.3 26.0 30.4 15.8 19.7 15.0 21.4

>

> rank(mtcars$mpg, 
+      na.last = TRUE, 
+      ties.method = c("max"))
 [1] 20 20 25 22 15 14  4 26 25 17 13 11 12  8  2  2  5 31 30 32 23  9  8  3 17 28 27 30 10 18  6 22

 

> ##----------------------- > ## rank() {base package} > ##----------------------- > > # if there are no ties(i.e., equal values), no problem at all > x <- c(1, 5, 9, 7) > rank(x) [1] 1 2 4 3 > > > # if there are ties, ties can be handled in several ways > y <- c(1, 1, 1, 5, 9, 7) > > # returns average, default setting > rank(y) [1] 2 2 2 4 6 5 > rank(y, ties.method = c("average")) [1] 2 2 2 4 6 5 > > # first occurrence wins > rank(y, ties.method = c("first")) [1] 1 2 3 4 6 5 > > # ties broken at random > rank(y, ties.method = c("random")) [1] 3 2 1 4 6 5 > > rank(y, ties.method = c("random")) # ...random one more time [1] 1 3 2 4 6 5 > > rank(y, ties.method = c("random")) # ...random...again [1] 1 2 3 4 6 5 > > # rank by max value as used classically > rank(y, ties.method = c("max")) [1] 3 3 3 4 6 5 > > # rank by min value as in Sports > rank(y, ties.method = c("min")) [1] 1 1 1 4 6 5

 

rank는 순위대로 정렬해주는게 아니라 순위의 색인을 나타내줍니다.

디폴트는 작은 값부터 1을 부여해주고, 큰 것 부터 1을 부여하려면 '-'를 붙여주면 됩니다.

 

동일한 값(Ties, i.e, equal values)이 있을 경우 rank() 함수는 "average" (default), "first", "random", "max", "min" 등의 옵션을 제공합니다.

 

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

 

Posted by R Friend R_Friend

댓글을 달아 주세요

  1. 신현호 2016.07.26 17:22  댓글주소  수정/삭제  댓글쓰기

    rank(mtcars$mpg) 를 실행시키면... 순위가 나오는데 순위가 소수점으로 나옵니다..ㅋㅋㅋ
    rank 함수가 순위를 출력시키는 원리가 무엇인거죠..ㅋㅋㅋ

    rank(mtcars$mpg)
    [1] 19.5 19.5 24.5 21.5 15.0 14.0 4.0 26.0 24.5 16.5 13.0 11.0 12.0 7.5
    [15] 1.5 1.5 5.0 31.0 29.5 32.0 23.0 9.0 7.5 3.0 16.5 28.0 27.0 29.5
    [29] 10.0 18.0 6.0 21.5

    • R Friend R_Friend 2016.07.26 17:50 신고  댓글주소  수정/삭제

      rank()함수는 크기 순서 색인을 반환합니다. 동일한 값(Ties, i.e, equal values)이 있을 경우 rank() 함수는 "average" (default), "first", "random", "max", "min" 등의 옵션을 제공하는데요, 댓글처럼 옵션을 명기하지 않을경우 "average"가 디폴트입니다. 옵션을 "first", "min", "max", "random" 중에서 분석 목적에 맞게 하나 선택해서 넣으면 소수점은 없어질겁니다

  2. 한종훈 2016.11.15 12:14  댓글주소  수정/삭제  댓글쓰기

    SAS만 10년쓰다 R 패키지를 하려니 헷갈리고 어려운게 너무 많습니다.
    한가지 여쭤보고 싶은데, 어쩌면 R에서는 굉장히 단순할 수도 있는데 제가 명령어나 함수를 몰라서 그럴 수 있다고 생각하시기를 부탁드립니다.

    심리검사 개발 및 통계 처리를 하다보면 변수들의 평균과 표준편차를 가지고 작업하는 경우가 많습니다. 예를 들어 X1, X2,...X150 의 응답값들을 1차 DB로 처리하고 그 뒤에 TX1(신규변수)=MEAN(OF X1, X3, X5) 와 같이 기존에 지정된 변수들의 평균값을 후속처리에 사용해야 하는 경우가 많습니다.

    그런 경우에는 R에서 어떻게 변수들의 합, 평균, 표준편차 등등의 값을 처리할 수 있을까요?

    • R Friend R_Friend 2016.11.15 12:38 신고  댓글주소  수정/삭제

      안녕하세요 한종훈님.

      저도 SAS 6년 사용하다가 R로 넘어올 때 무진 애먹었습니다. 프로그래밍 언어를 새로 배운다는게 쉽지가 않은거 같아요.

      데이터프레임 전처리에 강력한 dplyr 패키지 공부해보시면 좋을거 같습니다. 아래 링크부터 해서 dplyr 패키지 사용법 연재하고 있으니 참고하세요.

      http://rfriend.tistory.com/234

R 은 숫자형 벡터를 처리할 수 있는 편리한 함수를 다수 제공합니다.

 

이번 포스팅에서는 절대값 계산, 제곱근 계산, x 보다 크거나 같은 정수(지붕), x 보다 작거나 같은 정수(바닥), 소수점 이하는 잘라서 버리거나 반올림 하기, 로그 변환, 지수 변환, 팩토리얼 등의 벡터 처림 함수에 대해서 알아보도록 하겠습니다. 

 

문자형 벡터 처리 함수는 나중에 별도로 기회를 봐서 포스팅하도록 하겠습니다.

 

 

R 숫자형 벡터 처리 함수 

 

 

1) 절대값 계산 : abs(x)

 

> abs(10)
[1] 10
> abs(-10)
[1] 10

 

 

2) 제곱근 계산 : sqrt(x)

 

> sqrt(16) [1] 4 > sqrt(-16) # 허수는 NaN [1] NaN Warning message: In sqrt(-16) : NaNs produced

 

 

3) x 보다 크거나 같은 정수 (지붕 정수) : ceiling(x)

 

> ceiling(5.88)
[1] 6
> ceiling(6.00)
[1] 6

 

 

4) x 보다 작거나 같은 정수 (바닥 정수) : floor(x)

 

> floor(5.88)
[1] 5
> floor(5.00)
[1] 5

 

 

5) x 소숫점 이하는 잘라서 버림 : trunc(x)

 

> trunc(5.88)
[1] 5
> trunc(5.10)
[1] 5

 

 

6) x 를 소수점 n자리로 반올림 : round(x, digits=n)

 

> round(5.88, digits = 1)
[1] 5.9
> round(5.88, digits = 0)
[1] 6
> round(5.10, digits = 0)
[1] 5

 

 

7) x 를 밑이 n인 log 취하기 : log(x, base=n)

 

> log(10, base=2) # 밑이 2인 로그 [1] 3.321928 >

> log(10, base = exp(1)) # 자연로그 [1] 2.302585 >

> log(10) # 자연로그, base = exp(1) 을 생략해도 동일함 [1] 2.302585 >

> log(10, base=10) # 밑이 10인 상용로그 [1] 1 >

> log10(10) # 상용로그의 다른 표현법 [1] 1 

 

 

8) x 를 지수변환하기 : exp(x)

 

> exp(log(10, base=exp(1)))
[1] 10
> exp(1)
[1] 2.718282
> exp(10)
[1] 22026.47 

 

 

9) x factorial : factorial(x)

 

> factorial(2)
[1] 2
> factorial(3)
[1] 6
> factorial(4)
[1] 24
> factorial(5)
[1] 120 

 

 

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

 

Posted by R Friend R_Friend

댓글을 달아 주세요

  1. 김진양 2019.01.01 16:02  댓글주소  수정/삭제  댓글쓰기

    안녕하세요. r프렌드님! 데이터 분석 항상 재미있게 공부하고 있습니다.
    새해복 많이 받으세요^^

    다름 아니라, x를 지수로 변환하는 것의 의미가 잘 이해가 가지 않아서요.
    구글링, 네이버 검색을 했는데도 나오지가 않아서 질문드리게되었습니다.

    1을 지수로 변환했다는 뜻이 밑이 몇인 지수로 변환시키는건가요?

    제가 수학에 배움이 짧아 질문을 하면서도 정확한 용어를 지칭하기 어려워 댓글 달아주기 힘드실 것 같습니다. 죄송합니다!

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

 

 

 

 

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

 

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

 

Posted by R Friend R_Friend

댓글을 달아 주세요

엑셀에서 외부 텍스트 데이터를 불러올 때 (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() 함수는 조심해서 써야 합니다. 기계에서 일정한 간격으로 흐트러짐 없이 쏟아져나오는 센서 데이터와 같이 일정한 간격, 고정된 구조의 데이터라고 확신이 있을 때만 사용하시기 바랍니다.

 

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

 

Posted by R Friend R_Friend

댓글을 달아 주세요

  1. ruser 2017.04.15 21:19  댓글주소  수정/삭제  댓글쓰기

    항상 잘 보고 있습니다. 파이썬도 추가 되었군요, 함께 하겠습니다. ^^
    근데 제가 fwf 관련해서 궁금한 것이 있는데요,
    오라클 같은 DB에서는 컬럼의 길이를 설정할 때, 바이트로 따지는 것 같더라구요.
    이 때문에 해당 컬럼에 더블-바이트 문자인 한글을 입력하면 글자 하나당 2자리를 차지하게 되는데요, 여기서 이런 식으로 DB에서 생성된 데이터파일과(txt 등) 고정길이에 대한 메타데이터를 가지고 R의 read.fwf 등을 활용할 경우 컬럼 구분이 꼬일 수가 있더라구요.

    예를 들면 DB에서 길이 할당을 10으로 한 varchar2 컬럼에 한글로 "바나나"가 입력된 경우에,
    DB는 "바나나"를 6자리로 읽고 나머지를 스페이스 4자리로 해서 10자리를 채우는데,
    R에서는 "바나나"를 3자리로 읽고 나머지를 스페이스 4자리를 더해서 총 7자리로 읽어버리는 것이죠.

    혹시 이런 문제에 대한 해결 방법을 아시나요?

    LaF, readr 등 생소한 R 패키지들을 찾아보고 있는데, 좀처럼 답을 찾기가 어렵네요,,

    • R Friend R_Friend 2017.04.17 22:43 신고  댓글주소  수정/삭제

      안녕하세요 ruser님, R이랑 Python 사용하신다니 반갑니다.

      저는 질문해주신 것과 같은 문제를 겪어보지는 못해서요, 정확히는 모르겠는데요, 그냥 떠오르는 아이디어를 적어보자면요,

      R로 dbConnet 해서 할게 아니라 그냥 DB에서 text 파일로 exporting을 먼저 한 후에, R에서 read.fwf() 함수로 외부파일 불러오기를 하면 어떨까 싶은데요.

      DB에서 text 파일로 exporting할 때 white space 없어지게 해놓고, 한번 정돈된 text 파일을 R이 읽어오면 될거 같은데요. 제가 문제를 잘 이해하고 답변을 쓴건지 장담 못하겠네요. ^^;

  2. 박정욱 2017.05.08 15:56  댓글주소  수정/삭제  댓글쓰기

    항상 잘보고 공부하고 있습니다. 궁금한 점이 있어 문의 드립니다.

    매일 매일 하기와 같은 파일 이름으로 저장이 되는데

    T_Speed1_20170505, T_Speed1_20170506, .......

    T_Torque1_20170505, T_Torque1_20170506, ......

    이런한 파일이 10개정도 됩니다.이것을 파일 합치기를 적용하고 합니다.

    X <- c(20170505)

    data3 <- read.csv("Y:/SMART FACTORY/4. R data/file/T_Speed1_20170505.csv",header = TRUE, stringsAsFactors = F)

    data4 <- read.csv("Y:/SMART FACTORY/4. R data/file/T_Torque1_20170505.csv",header = TRUE, stringsAsFactors = F)

    T_Speed1_X,T_Torque1_X로 X라는 변수로 지정 가능 할까요??

    이게 안되면 어떤한 방법이 있을까요??





    • R Friend R_Friend 2017.05.08 17:01 신고  댓글주소  수정/삭제

      안녕하세요 박정욱님,

      아래에 포스팅해놓은 글 참고하시기 바랍니다.

      (1) '폴더 내 여러개 파일들을 Loop 돌려서 자동으로 불러와서 하나의 객체로 합치기'
      => http://rfriend.tistory.com/219

      (2) assign 함수를 사용해서 객체의 이름에 다른 이름 추가하기
      => http://rfriend.tistory.com/108

 

지난번 포스팅에서 데이터 프레임을 편리하게 사용할 때 사용할 수 있는 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()는 아마 자주 사용하는 함수일터이니 제대로 알고 사용해야 에러를 피해갈 수 있겠지요?!

 

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

 

Posted by R Friend R_Friend

댓글을 달아 주세요

 

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

 

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

 

Posted by R Friend R_Friend

댓글을 달아 주세요

  1. HJE 2018.03.24 17:21  댓글주소  수정/삭제  댓글쓰기

    블로그를 통해 R을 쉽게 배우고 있습니다. ^^

    이 포스트의 마지막 부분에서

    'summary() 함수로 실린더(cyl: cylinder)별로 연비(mpg: mileage per gasolin)도 구하..'
    이렇게 나와있는데요.

    mpg의 평균, 중앙값, quartiles를 구하신 거 맞지요?
    실린더별로 연비를 구한다는 것은 어떤 뜻인지 풀어서 설명해주실 수 있을까요? ^^

    • R Friend R_Friend 2018.03.24 17:51 신고  댓글주소  수정/삭제

      안녕하세요 HJE님,
      댓글에 질문 남겨주신 부분을 보니 제가 포스팅을 잘못 썼던 거였네요. ^^; 제가 잘못썼던 포스팅 본문을 수정했습니다. 혼선을 드려서 죄송합니다. 그리고 제가 수정할 수 있도록 댓글 남겨주셔서 감사합니다.

      연속형 변수에 대한 그룹별(요인별) 요약통계량을 구할 수 있는 R 패키지와 함수는 아래의 포스팅을 참고하시면 됩니다. 다시 한번 댓글 감사드립니다.

      => http://rfriend.tistory.com/125

 

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 내의 모든 변수에 공통으로 적용하라는 뜻입니다)

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

 

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

 

Posted by R Friend R_Friend

댓글을 달아 주세요

지난 포스팅에서

 

- 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 되어 저장되었음을 확인할 수 있습니다.

 

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

 

Posted by R Friend R_Friend

댓글을 달아 주세요

  1. Jun 2015.12.21 18:43  댓글주소  수정/삭제  댓글쓰기

    1편부터 쭉 읽으며 따라하고 있습니다.
    최근 기존에 매틀랩과 엑셀을 사용해 데이터처리하다 한계를 느껴 새로운 툴을 찾아보고있었는데 너무 좋은 강좌 감사드립니다!!

  2. 2016.01.13 21:02  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

    • R Friend R_Friend 2016.01.13 23:55 신고  댓글주소  수정/삭제

      전지환 님, 아래처럼 lm() 함수를 이용해서 2줄 프로그램 입력하시면 됩니다.

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

      제가 블로그 포스팅할 때 위의 프로그램 2줄을 실수로 빼먹었었네요. ^^;
      최근에 선형대수 관련해서 연재하고 있는데요, 앞으로 5개 정도 더 선형대수 연재한 후에 회귀분석에 대해서 포스팅해보려고 합니다. 회귀분석이 예측에 아주 많이 활용이 되는 편이어서 중요한지라 자세히 풀어볼까 생각중입니다.

    • 2016.01.17 18:49  댓글주소  수정/삭제

      비밀댓글입니다

    • R Friend R_Friend 2016.01.17 22:28 신고  댓글주소  수정/삭제

      전지환님, 꾸준히 하시는 모습 보기좋습니다. 화이팅하시구요! ^^

  3. 함께멀리 2017.12.15 01:34  댓글주소  수정/삭제  댓글쓰기

    자꾸 문의 드려 죄송합니다.
    매일 1개 강의는 보자는 식으로, 퇴근후에 별도로 공부하고 있습니다.
    근데 짜꾸 error가 발생하면서, txt file 내에 data 저장이 안되네요 ㅜ.ㅜ 머가 문제일까요?

    > write.table(d.f_h_w,"c:/users/jujak/documents/r/ex/lm_fit_h_w.txt",
    + sep = ",",
    + row.names = FALSE,
    + quote = FALSE,
    + append = TRUE)
    Warning message:
    In write.table(d.f_h_w, "c:/users/jujak/documents/r/ex/lm_fit_h_w.txt", :
    열의 이름들을 파일에 추가합니다
    > capture.output(summary(lm_fit_h_w),
    + file = "c:users/jujak/documents/r/ex/lm_fit_h_w.txt",
    + append = TRUE)
    Error in file(file, if (append) "a" else "w") :
    cannot open the connection
    In addition: Warning message:
    In file(file, if (append) "a" else "w") :
    cannot open file 'c:users/jujak/documents/r/ex/lm_fit_h_w.txt': No such file or directory

    • R Friend R_Friend 2017.12.16 00:30 신고  댓글주소  수정/삭제

      안녕하세요.

      문의해주신 R Script의 경로에서 "c:users" 에서 'c:'와 'users' 사이에 '/'가 빠져서 그런것 같습니다. (No such file or directory 이라는 에러 메시지가 뜬 이유)

      (수정 전)
      file = "c:users/jujak/documents/r/ex/lm_fit_h_w.txt"

      => (수정 후) file = "c:/users/jujak/documents/r/ex/lm_fit_h_w.txt"

  4. 김진양 2018.07.25 23:52  댓글주소  수정/삭제  댓글쓰기

    안녕하세요. 항상 감사히 잘 보고 있습니다!
    뭐 하나 질문해도될까요?
    현재 for 구문을 이용해 여러개의 df를 생성하고, 하나의 엑셀 파일에 전부 집어넣고 싶은데
    마지막 df만 엑셀에 저장이되네요.
    혹시 어떤 부분이 잘못되었는지 여쭤봐도 괜찮을까요?
    수식은
    urlbase<-"https://search.shopping.naver.com/search/all.nhn?query="
    low<-c("에어팟","코카콜라","건전지","삼다수")
    low
    for( i in low){
    url<-paste(urlbase, i ,"&cat_id=&frm=NVSHATC",sep="")
    nv<-read_html(url, encoding = "UTF-8")
    st<-html_nodes(nv, '.mall_name')%>%html_text()
    st<-st[1:10]
    price3<-html_nodes(nv, '._lowPriceByMall')%>%html_nodes('.price')%>%html_text()
    price3<-gsub('최저가','',price3)
    price3<-price3[1:10]
    df<-data.frame(가게명=st, 가격=price3)
    df
    df<-rbind(df, data.frame(가게명=url, 가격="r"))
    print(df)
    write.xlsx(, file="D:/456.xlsx", col.names=TRUE)
    }
    if(df[1,1]=="위메프"){
    print("True")
    }else{
    write.xlsx(df, file="D:/789.xlsx", append=TRUE)
    }
    }

    입니다.

    • R Friend R_Friend 2018.07.27 01:01 신고  댓글주소  수정/삭제

      안녕하세요 김진양 님, 오늘 저녁 늦께까지 회사 밋업행사에서 발표하는게 있어서 이제서야 봤네요.

      코드를 직접 돌려보지는 못했구요, 눈으로 보고서 고쳐보면 좋겠다 싶은 2군데 수정한 코드를 아래에 붙여놓습니다.

      제가 내일 새벽에 차타고 나갔다가 토요일 저녁에야 집에 돌아오는데요, 그 사이에는 컴퓨터를 사용할 수 없습니다. 혹시 만약에 아래 코드가 작동을 안하는데 급하신거면 제 답글 기다리지 마시고 주위에 다른 분에 도움을 요청하셔야 할거 같습니다.

      urlbase<-"https://search.shopping.naver.com/search/all.nhn?query="
      low<-c("에어팟","코카콜라","건전지","삼다수")
      low

      # (1) make blank dataframe
      df_all <- data.frame()

      for( i in low){
      url<-paste(urlbase, i ,"&cat_id=&frm=NVSHATC",sep="")
      nv<-read_html(url, encoding = "UTF-8")
      st<-html_nodes(nv, '.mall_name')%>%html_text()
      st<-st[1:10]
      price3<-html_nodes(nv, '._lowPriceByMall')%>%html_nodes('.price')%>%html_text()
      price3<-gsub('최저가','',price3)
      price3<-price3[1:10]
      df<-data.frame(가게명=st, 가격=price3)

      # (2) adding append=TRUE option
      write.xlsx(df, file="D:/456.xlsx", col.names=TRUE, append=TRUE)

      df_all <- rbind(df, data.frame(가게명=url, 가격="r"))
      print(df)

      }

      # (3) used df_all
      if(df[1,1]=="위메프"){
      print("True")
      }else{
      write.xlsx(df_all, file="D:/789.xlsx")
      }

  5. 김진양 2018.07.29 00:17  댓글주소  수정/삭제  댓글쓰기

    안녕하세요! 알프렌드님 친절한 답변감사드립니다!!
    말씀해주신 수식대로 해보았더니, Error in .jcall(wb, "Lorg/apache/poi/ss/usermodel/Sheet;", "createSheet", :
    java.lang.IllegalArgumentException: The workbook already contains a sheet of this name
    라는 문구가 나오면서 되지가 않습니다.
    구글링 해본 결과, append 명령어가 새로운 Sheet에 저장한다는 것 같은데, 그와 관련한 문제인 것 같습니다! 저는 원래 하나의 시트에 모두 나오게 하려고 했는데 그렇게는 안되는걸까요?
    질문이 꼬리에 꼬리를 물고 나와서 죄송합니다. 크롤링까지는 어떻게 꾸역꾸역 해보았는데 여기서 막히네요.... 친절한답변감사합니다^^

    • R Friend R_Friend 2018.07.30 13:14 신고  댓글주소  수정/삭제

      안녕하세요 김진양님,
      아래 코드 참고하시기 바랍니다.
      (폴더 안에 기존에 만들어놓은 456.xlsx, 789.xlsx 파일이 남아있으면 에러가 나니 미리 삭제하고 아래 코드를 실행하시기 바랍니다)

      # clear all
      rm(list=ls())

      # install and load libries
      install.packages("textreadr")
      install.packages("rvest")
      install.packages("xlsx")

      library(textreadr)
      library(rvest)
      library(xlsx)

      urlbase<-"https://search.shopping.naver.com/search/all.nhn?query="
      low <- c("에어팟","코카콜라","건전지","삼다수")
      low

      # for loop statement
      for (i in low){
      url <- paste(urlbase, i ,"&cat_id=&frm=NVSHATC",sep="")
      nv <- read_html(url, encoding = "UTF-8")
      st <- html_nodes(nv, '.mall_name')%>%html_text()
      st <- st[1:10]
      price3 <- html_nodes(nv, '._lowPriceByMall') %>% html_nodes('.price') %>% html_text()
      price3 <- gsub('최저가','',price3)
      price3 <- price3[1:10]
      df<-data.frame(가게명=st, 가격=price3)

      # append url to df
      df <- rbind(df, data.frame(가게명=url, 가격="r"))

      # adding sheetName
      write.xlsx(df, file="C:/Users/admin/Documents/456.xlsx",
      sheetName=i, # excel sheet per each product or brand
      col.names=TRUE,
      append=TRUE)

      # if else condition statement
      if(df[1,1]=="위메프"){
      print("위메프 True")
      } else {
      write.xlsx(df, file="C:/Users/admin/Documents/789.xlsx",
      sheetName=i,
      col.names=TRUE,
      append=TRUE)
      }

      # check progress
      print(paste0(i, " has been completed."))
      }

    • 김진양 2018.07.30 21:58  댓글주소  수정/삭제

      R프렌드님 감사합니다! 드디어 해결했습니다^^
      R프렌드님이 주신 코드를 단순히 copy & paste하는 것이 아니라, 찬찬히 하나하나 공부해보았습니다.
      제 실수는 write.xlsx과정에서 sheet를 추가하려한다면 write.xlsx(~~,~~, sheetname=i)로 설정하지 않은 것임을 깨달을 수 있었습니다.
      진심으로 감사의 말씀을 드립니다^^

      혹여나 실례가 되지 않는다면, for반복문에서 도출되는 데이터셋을 sheet별이 아닌, 하나의 sheet에 순차적으로 나타내는 방법은 없는지 여쭤볼 수 있을까요?

      해당 사항을 해결하기 위해 일주일동안 구글링을 했는데 해결방법을 알지 못해, 부끄러움을 무릅쓰고 이렇게 댓글을 남겨봅니다.

      제가 이해를 잘 못하고, 여러번 알프렌드님을 귀찮게 해드렸는데도 친절하게 대답해주셔서 정말로 감사합니다! 이번 일을 계기로 알프렌드님과의 인연을 소중히 생각하고 오랫동안 간직해나가겠습니다^^ 감사합니다.

    • R Friend R_Friend 2018.07.30 22:45 신고  댓글주소  수정/삭제

      안녕하세요 김진양님,
      아래 코드 참고하시기 바랍니다.
      원하시는 결과이기 바래요.

      # clear all
      rm(list=ls())

      # install and load libries
      # install.packages("textreadr")
      # install.packages("rvest")
      # install.packages("xlsx")

      library(textreadr)
      library(rvest)
      library(xlsx)

      urlbase<-"https://search.shopping.naver.com/search/all.nhn?query="
      low <- c("에어팟","코카콜라","건전지","삼다수")
      low

      # making a blank DataFrame to store
      df_all <- data.frame()

      # for loop statement
      for (i in low){
      url <- paste(urlbase, i ,"&cat_id=&frm=NVSHATC",sep="")
      nv <- read_html(url, encoding = "UTF-8")
      st <- html_nodes(nv, '.mall_name')%>%html_text()
      st <- st[1:10]
      price3 <- html_nodes(nv, '._lowPriceByMall') %>% html_nodes('.price') %>% html_text()
      price3 <- gsub('최저가','',price3)
      price3 <- price3[1:10]
      df<-data.frame(item=i, 가게명=st, 가격=price3)

      # append url info to df_all
      df <- rbind(df, data.frame(item=i, 가게명=url, 가격="r"))

      # combining df to df_all one by one
      df_all <- rbind(df_all, df)

      # check progress
      print(paste0(i, " has been completed."))
      }

      # exporting df_all to excel
      write.xlsx(df_all,
      file="C:/Users/admin/Documents/df_all.xlsx",
      col.names=TRUE)

  6. 김진양 2018.08.02 08:15  댓글주소  수정/삭제  댓글쓰기

    알 프렌드님 안녕하세요^^ 일이 너무 바빠 프로구램을 돌려보질 못했습니다(프로그램 알은 집에서 취미로 공부하고있어서요) 출근길에 알프렌드님 블로그를 돌려 감사인사 전해드립니다.
    얼른 집에 가서 해보고 말씀드릴게요. 너무 설레네요 감사합니다^^

    • R Friend R_Friend 2018.08.02 10:44 신고  댓글주소  수정/삭제

      잘 되면 좋겠네요

    • 김진양 2018.08.05 12:19  댓글주소  수정/삭제

      알프렌드님 감사합니다!!! 원하던 결과물을 도출해냈습니다.
      df에 있어서 rbind를 통해 item명을 i로 잡고 하니 해결이 가능했네요!
      뒤늦게 해결해서 죄송합니다.
      한달여가량 계속 고민하면서 알프렌드님을 알게되고, 알프렌드님의 친절한 교육으로 인해 결국 원하던 결과물을 도출해낼 수 있었습니다.
      진심으로 감사드리며, 블로그 자주 놀러와서 더욱 더 공부하는 학생이 될게요^^

    • R Friend R_Friend 2018.08.05 12:20 신고  댓글주소  수정/삭제

      원하던 결과를 얻어서 다행입니다. ^^

  7. 이수진 2019.10.16 10:48  댓글주소  수정/삭제  댓글쓰기

    안녕하세요. 267개 데이터프레임을 for문으로 각각 회귀분석 돌리고 267개 결과들을 한꺼번에 엑셀파일에 넣으려고합니다. 혹시 방법이있을까요?
    최종 데이터는 df_max_split 입니다!
    [code]
    #logistic regression#

    require(readxl)

    #01#[데이터 불러오기]

    # 작업공간 설정하기(이곳에 엑셀 파일이 있다고 가정)
    setwd("C:/Users/DV-Sub02/Desktop/한주금속")

    # 작업공간에 있는 엑셀 파일의 목록을 저장
    fileNames = list.files(pattern="xlsx")

    # 엑셀 파일의 이름과 동일하게 데이터생성
    for(i in 1:length(fileNames)){
    data = read_excel(path=fileNames[i], sheet=1, col_names=TRUE)
    assign(x=fileNames[i], value=data)
    }

    # 엑셀 파일 합치기
    df_max <- rbind(`201805.xlsx`,`201806.xlsx`,`201807.xlsx`,`201808.xlsx`,`201809.xlsx`,`201810.xlsx`,`201811.xlsx`,`201812.xlsx`,`201901.xlsx`,`201902.xlsx`,`201903.xlsx`,`201904.xlsx`)


    # 전부 고려
    ## 라인x품명x금형명
    df_max$case <- paste(df_max $작업라인,df_max $품명,df_max $금형명)


    # 한가지 고려
    ## 라인
    #df_max_time_Defectiverate$case <- paste(df_max_time_Defectiverate$작업라인)
    ## 품명
    #df_max_time_Defectiverate$case <- paste(df_max_time_Defectiverate$품명)
    ## 금형명
    #df_max_time_Defectiverate$case <- paste(df_max_time_Defectiverate$금형명)

    # 두가지 고려
    ## 라인x품명
    #df_max_time_Defectiverate$case <- paste(df_max_time_Defectiverate$작업라인,df_max_time_Defectiverate$품명)
    ## 라인x금형명
    #df_max_time_Defectiverate$case <- paste(df_max_time_Defectiverate$작업라인,df_max_time_Defectiverate$금형명)
    ## 품명x금형명
    #df_max_time_Defectiverate$case <- paste(df_max_time_Defectiverate$품명,df_max_time_Defectiverate$금형명)

    #dim(df_max_time_Defectiverate)

    # 데이터 나누기
    df_max_split <- split(df_max,df_max$case)

    • R Friend R_Friend 2019.10.16 11:40 신고  댓글주소  수정/삭제

      안녕하세요.
      제가 직장인인데요, 이번주에 너무 바빠서 일요일 저녁에 잠깐 시간이 날거 같습니다. 혹시 급하신거면 제가 바로 도와드릴수 없습니다. 죄송합니다. ㅠ.ㅠ

  8. 이수진 2019.10.16 11:44  댓글주소  수정/삭제  댓글쓰기

    도움주실 수 있으면 언제든지 괜찮습니다! 그동안 혼자 연구해보고 있겠습니다 감사합니다^^

    • R Friend R_Friend 2019.10.16 11:45 신고  댓글주소  수정/삭제

      지금은 개별 회귀분석 결과를 개별 엑셀에 내려보낸 디음에, 나중에 합체려고 하시는건가봐요?

      이 포스팅의 댓글 란에 보시면 엑셀로 내보내는 코드 있는데요, 혹시 그거에 참고하실만한게 있으려나요?

  9. 이수진 2019.10.16 13:14  댓글주소  수정/삭제  댓글쓰기

    네 개별 회귀분석 결과를 개별 엑셀에 내보내거나 한번에 다 같이 내보내는 방법 살펴보고있어요
    댓글 참고해서 한번 해보겠습니다 ㅎㅎ

  10. tnwls2 2019.10.16 15:56  댓글주소  수정/삭제  댓글쓰기

    안녕하세요. 각 데이터별 회귀분석 결과들을 df_max_split_GLM_result이름으로 리스트 형태로 저장했습니다. 그런데 맨 마지막 코드에서 for문으로 capture.output을 사용하니까 첫번째 리스트인 df_max_split_GLM_result1만 리스트개수만큼 반복해서 메모장에 저장되었습니다.ㅠㅠ 혹시 코드만 보시고 어떤게 문제인지 여쭤봐도될까요? 자꾸 문의드려 죄송합니다 ㅠㅠ
    #logistic regression#

    require(readxl)

    #01#[데이터 불러오기]

    # 작업공간 설정하기(이곳에 엑셀 파일이 있다고 가정)
    setwd("C:/Users/DV-Sub02/Desktop/한주금속")

    # 작업공간에 있는 엑셀 파일의 목록을 저장
    fileNames = list.files(pattern="xlsx")

    # 엑셀 파일의 이름과 동일하게 데이터생성
    for(i in 1:length(fileNames)){
    data = read_excel(path=fileNames[i], sheet=1, col_names=TRUE)
    assign(x=fileNames[i], value=data)
    }

    # 엑셀 파일 합치기
    df_max <- rbind(`201805.xlsx`,`201806.xlsx`,`201807.xlsx`,`201808.xlsx`,`201809.xlsx`,`201810.xlsx`,`201811.xlsx`,`201812.xlsx`,`201901.xlsx`,`201902.xlsx`,`201903.xlsx`,`201904.xlsx`)


    # 전부 고려
    ## 라인x품명x금형명
    df_max$case <- paste(df_max $작업라인,df_max $품명,df_max $금형명)


    # 데이터 나누기
    df_max_split <- split(df_max,df_max$case)


    #GLM
    for (i in 1:length(df_max_split)) {
    assign(paste0("df_max_split_GLM_result", i),glm(df_max_split[[i]]$양품판정결과~df_max_split[[i]]$'전자교반 가동시간'+df_max_split[[i]]$'설비가동 CT'+df_max_split[[i]]$'제품생산 CT'+df_max_split[[i]]$저속구간속도+df_max_split[[i]]$가동보온로+df_max_split[[i]]$용탕량,data=df_max_split[[i]],family="binomial"))
    }


    cat("data is as follows:","\n","\n",file="C:/Users/DV-Sub02/Desktop/한주금속/glm.txt",append=TRUE)

    for (i in 1:length(df_max_split)) {
    capture.output(summary(df_max_split_GLM_result[[i]]),file="C:/Users/DV-Sub02/Desktop/한주금속/glm2.txt",append=TRUE)
    }

    • R Friend R_Friend 2019.10.16 16:17 신고  댓글주소  수정/삭제

      안녕하세요.
      코드만 보고 테스트는 못해봐서 틀릴수도 있는데요, GLM 부분을 수정해보실래요?

      # GLM
      df_max_split_GLM_result <- {}

      for (i in 1:length(df_max_split)) {
      df_max_split_GLM_result[[i]] <- glm(동일)
      }

  11. tnwls2 2019.10.16 16:25  댓글주소  수정/삭제  댓글쓰기

    저렇게 해서 결과는 나왔는데 결과들에 대한 summary가 리스트형태라서 데이터프레임처럼 저장이 안되네요..ㅠㅠ

지난 포스팅에서 외부 파일을 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()은 다음번 포스팅에 소개하도록 하겠습니다. 

 

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


Posted by R Friend R_Friend

댓글을 달아 주세요

  1. 2016.07.17 22:25  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  2. 2016.07.26 15:34  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

    • R Friend R_Friend 2016.07.26 16:02 신고  댓글주소  수정/삭제

      cat() 함수는 "분석 결과나 텍스트"를 외부 파일로 저장할 때 씁니다.

      write.table은 "데이터프레임"을 외부 파일로 내보내서 저장할 때 사용합니다.

  3. 2016.10.04 15:03  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  4. 함께멀리 2017.12.14 00:34  댓글주소  수정/삭제  댓글쓰기

    정성스럽게 써주신 블로그 글을 보면서 혼자 R을 공부하고 있는 사람입니다. 감사합니다.
    data를 cat()함수를 통해서 아래와 같이 진행해 봤는데, 자꾸 error가 나면서 등록이 안됩니다.
    어디가 잘못된 것인지요??

    > cat ("data is as follow","/n",
    Error: unexpected '>' in ">"
    > x,"/n"
    Error: unexpected ',' in " x,"
    > file = "C:/Users/Jujak/Documents/R/ex/data_x.txt"

  5. 인사하는너구리 2018.08.17 11:29  댓글주소  수정/삭제  댓글쓰기

    R에 관심있어서 혼자 공부하는 학생인데 너무 잘보고있습니다. 감사해요!!!
    write.table 실행시 '열의 이름들을 파일에 추가합니다'라는 warning message가 뜨더라구요
    구글링 해보니 "col.name = FALSE" 추가해서 해결했습니다.
    저와 같은 증상 나타나시는 분들은 참고하셨습면 좋겠네요

    • R Friend R_Friend 2018.08.17 11:41 신고  댓글주소  수정/삭제

      안녕하세요 인사하는 너구리님,
      댓글 감사합니다. 안내해주신 부분을 포스팅 본문에 추가해서 다른 분들도 쉽게 볼수 있도록 공유하겠습니다. 좋은 정보 감사합니다.

  6. R Friend R_Friend 2018.09.12 16:03 신고  댓글주소  수정/삭제  댓글쓰기

    퇴근 후에 저녁때 살펴보고 답글 달께요.

  7. 안녕하세요 2018.09.27 15:08  댓글주소  수정/삭제  댓글쓰기

    write.table(dataset_1, "C:/Program Files/RStudio/R/cust_profile.txt",
    sep = "",
    row.names = FALSE,
    quote = FALSE,
    ppend = TRUE,
    na = "NA"
    )
    로 입력하였을때
    Error in write.table(dataset_1, "C:/Program Files/RStudio/R/cust_profile.txt", :
    unused argument (ppend = TRUE)
    라고 하면서 작동이 안 되는데 왜 그런지 알 수 있을까요?

  8. R Friend R_Friend 2018.09.27 15:12 신고  댓글주소  수정/삭제  댓글쓰기

    ppend 를 append 로 바꿔서 해보실래요?