Tools/R (59)

반응형

R Default library path 바꾸기 (공용 라이브러리 경로 설정)


.libPaths() 를 하면 현재 사용하고 있는 라이브러리 경로들이 나온다.


[1] "C:/Users/사용자이름/Documents/R/win-library/3.3"

[2] "C:/Program Files/R/R-3.3.2/library"


R은 여기서 첫 번째 element를 Default로 쓰는데, 이것은 보통 개인 폴더로 잡혀 있다. 

하지만 다중 사용자 환경에서는 내가 설치한 라이브러리를 남이 사용하도록 해야할 경우도 있는데 이때는 아래와 같이 하면 된다. 


1. R_LIBS 환경변수를 공용 라이브러리 경로로 설정함 

2. R에서 Sys.getenv("R_LIBS")를 통해 환경변수가 잘 잡혔는지를 볼 수 있다.

3. .libPaths()를 다시 입력하면 공용 라이브러리 경로가 1번으로 잡혀있는 것을 확인할 수 있다. 

 

[1] "C:/Program Files/R/R-3.3.2/library" 

[2] "C:/Users/사용자이름/Documents/R/win-library/3.3"


이후에는 패키지를 설치하면 모든 사용자가 이용할 수 있게 된다. 

반응형
반응형


PBC 데이터를 통한 생존분석


PBC 데이터 다운받을 수 있는 사이트

http://www4.stat.ncsu.edu/~boos/var.select/pbc.html

http://www4.stat.ncsu.edu/~boos/var.select/pbc.dat.txt


이 데이터셋은 mayo clinic에서 수집된 데이터로 일차성 담즙성 간경화증(primary biliary cirrhosis) 환자들의 생존에 대한 데이터입니다. 


데이터 핸들링

library(survival)

data <- read.table("pbc.dat")

# Column rename
colnames(data) <- c('id', 'futime', 'status', 'drug', 'age', 'sex', 'ascites', 'hepato', 'spiders', 'edema', 'bili', 'chol', 'albumin', 'copper', 'alk_phos', 'sgot', 'trig', 
                   'platelet', 'protime', 'stage')

head(data)


id
futime
status
drug
age
sex
ascites
hepato
spiders
edema
bili
chol
albumin
copper
alk_phos
sgot
trig
platelet
protime
stage
1400212146411111.014.52612.601561718.0137.9517219012.24
24500012061710110.01.13024.14547394.8113.528822110.63
31012212559400000.51.41763.48210516.096.105515112.04
41925211999410110.51.82442.54646121.860.639218310.34
51504121391810110.03.42793.53143671.0113.157213610.93
62503222420110100.00.82483.9850944.093.0063.11.03

생존분석 자료의 기본 자료 구성


1. Survival 데이터에서는 time을 나타내는 변수와 event를 나타내는 변수가 있다. 

2. time은 event 까지의 시간을 나타내며, 

3. event 변수는 우리의 관심 event (예를 들어, 사망) 혹은 censoring을 나타낸다. (이는 주로 0, 1로 나타내어진다.)


PBC 데이터에서는  status = 0=alive, 1=liver transplant, 2=dead 인데,  0,1을 중도 절단된 censoring, 2 를 관심 event로 코딩을 해봅시다.

data$status[(data$status == 1)] = 0
data$status[(data$status == 2)] = 1


drug = 1 : 페니실린

drug = 2 : 플라시보이므로 , 해석상의 이점을 얻기 위해

drug = 1 페니실린, drug = 0은 플라시보로 재코딩해줍니다.


data <- data[data$drug != '.', ]
data$drug <- as.character(data$drug)
data$drug[(data$drug == 2)] = 0
data$drug <- factor(data$drug)


1. KM estimation


우선 Survival function을 추정하는 비모수적인 방법으로 많이 쓰이는 Kaplan-Meier analysis 를 해보겠습니다.


# event, censoring 구분
Y = Surv(data$futime, data$status)

# KM estimation
fit = survfit(Y~data$drug)
summary(fit)


우선 Surv라는 함수를 통해 무엇이 time과 event인지를 알려줍니다. 그리고 drug에 따라 생존을 분석할 것이므로 ~data$drug를 입력하면 아래처럼 lifetable을 만들어줍니다.


Call: survfit(formula = Y ~ data$drug)

                data$drug=0 
 time n.risk n.event survival std.err lower 95% CI upper 95% CI
   51    154       1    0.994 0.00647        0.981        1.000
   77    153       1    0.987 0.00912        0.969        1.000
  110    152       1    0.981 0.01114        0.959        1.000
  130    151       1    0.974 0.01282        0.949        0.999
  186    150       1    0.968 0.01428        0.940        0.996
  191    149       1    0.961 0.01559        0.931        0.992
  207    148       1    0.955 0.01679        0.922        0.988
  216    147       1    0.948 0.01788        0.914        0.984
  264    146       2    0.935 0.01986        0.897        0.975
  304    144       1    0.929 0.02075        0.889        0.970
  321    143       1    0.922 0.02160        0.881        0.965
  326    142       1    0.916 0.02240        0.873        0.961
  460    141       1    0.909 0.02317        0.865        0.956
  549    140       1    0.903 0.02389        0.857        0.951
  552    139       1    0.896 0.02459        0.849        0.946
  597    138       1    0.890 0.02525        0.841        0.941
  611    137       1    0.883 0.02589        0.834        0.935
  708    136       1    0.877 0.02650        0.826        0.930
  733    135       1    0.870 0.02709        0.819        0.925
  769    134       1    0.864 0.02765        0.811        0.920
  786    133       1    0.857 0.02820        0.804        0.914
  790    131       1    0.851 0.02873        0.796        0.909
  797    130       1    0.844 0.02925        0.789        0.903
  850    128       1    0.837 0.02975        0.781        0.898
  853    127       1    0.831 0.03024        0.774        0.892
  859    126       1    0.824 0.03071        0.766        0.887
  890    125       1    0.818 0.03116        0.759        0.881
  930    124       1    0.811 0.03160        0.751        0.875
  943    123       1    0.804 0.03203        0.744        0.870
  974    122       1    0.798 0.03244        0.737        0.864
 1080    118       1    0.791 0.03286        0.729        0.858
 1165    115       1    0.784 0.03328        0.722        0.852
 1212    114       1    0.777 0.03370        0.714        0.846
 1217    111       1    0.770 0.03411        0.706        0.840
 1356    103       1    0.763 0.03459        0.698        0.834
 1413    101       1    0.755 0.03506        0.690        0.827
 1427     98       1    0.748 0.03554        0.681        0.821
 1444     95       1    0.740 0.03603        0.672        0.814
 1487     93       1    0.732 0.03651        0.664        0.807
 1536     91       1    0.724 0.03698        0.655        0.800
 1786     79       1    0.715 0.03763        0.645        0.792
 1847     76       1    0.705 0.03829        0.634        0.784
 2090     69       1    0.695 0.03908        0.622        0.776
 2419     56       1    0.683 0.04030        0.608        0.766
 2466     53       1    0.670 0.04155        0.593        0.756
 2503     51       1    0.657 0.04276        0.578        0.746
 2769     40       1    0.640 0.04473        0.558        0.734
 2796     38       1    0.623 0.04662        0.538        0.722
 2847     35       1    0.605 0.04857        0.517        0.709
 3090     32       1    0.587 0.05060        0.495        0.695
 3170     29       1    0.566 0.05275        0.472        0.680
 3244     28       1    0.546 0.05460        0.449        0.664
 3358     26       1    0.525 0.05640        0.425        0.648
 3395     24       1    0.503 0.05814        0.401        0.631
 3428     22       1    0.480 0.05983        0.376        0.613
 3445     21       1    0.457 0.06119        0.352        0.595
 3762     15       1    0.427 0.06427        0.318        0.573
 3839     13       1    0.394 0.06719        0.282        0.551
 3853     12       1    0.361 0.06916        0.248        0.526

                data$drug=1 
 time n.risk n.event survival std.err lower 95% CI upper 95% CI
   41    158       1    0.994 0.00631        0.981        1.000
   71    157       1    0.987 0.00889        0.970        1.000
  131    156       1    0.981 0.01086        0.960        1.000
  140    155       1    0.975 0.01250        0.950        0.999
  179    154       1    0.968 0.01393        0.941        0.996
  198    153       1    0.962 0.01521        0.933        0.992
  223    152       1    0.956 0.01637        0.924        0.988
  334    151       1    0.949 0.01744        0.916        0.984
  348    150       1    0.943 0.01844        0.908        0.980
  388    149       1    0.937 0.01937        0.900        0.975
  400    148       1    0.930 0.02025        0.892        0.971
  515    147       1    0.924 0.02108        0.884        0.966
  673    145       1    0.918 0.02187        0.876        0.962
  694    144       1    0.911 0.02263        0.868        0.957
  750    141       1    0.905 0.02337        0.860        0.952
  762    140       1    0.898 0.02408        0.852        0.947
  799    139       1    0.892 0.02476        0.845        0.942
  824    138       1    0.885 0.02541        0.837        0.937
  904    134       1    0.879 0.02607        0.829        0.931
  971    132       1    0.872 0.02671        0.821        0.926
  980    131       1    0.866 0.02732        0.814        0.921
  999    130       1    0.859 0.02791        0.806        0.915
 1000    129       1    0.852 0.02848        0.798        0.910
 1012    128       1    0.846 0.02902        0.791        0.904
 1037    127       1    0.839 0.02955        0.783        0.899
 1077    126       1    0.832 0.03005        0.775        0.893
 1083    125       1    0.826 0.03054        0.768        0.888
 1152    124       1    0.819 0.03101        0.760        0.882
 1170    122       1    0.812 0.03148        0.753        0.876
 1191    121       2    0.799 0.03236        0.738        0.865
 1235    117       1    0.792 0.03279        0.730        0.859
 1297    114       1    0.785 0.03323        0.723        0.853
 1350    111       1    0.778 0.03368        0.715        0.847
 1360    110       1    0.771 0.03411        0.707        0.841
 1434    105       1    0.764 0.03456        0.699        0.834
 1492    100       1    0.756 0.03505        0.690        0.828
 1576     97       1    0.748 0.03554        0.682        0.821
 1657     93       1    0.740 0.03606        0.673        0.814
 1682     92       1    0.732 0.03655        0.664        0.807
 1690     91       2    0.716 0.03748        0.646        0.793
 1741     87       1    0.708 0.03794        0.637        0.786
 1827     82       1    0.699 0.03845        0.628        0.779
 1925     78       1    0.690 0.03899        0.618        0.771
 2055     72       1    0.681 0.03960        0.607        0.763
 2081     71       1    0.671 0.04019        0.597        0.755
 2105     70       1    0.661 0.04074        0.586        0.746
 2224     65       1    0.651 0.04137        0.575        0.738
 2256     63       1    0.641 0.04198        0.564        0.729
 2288     61       1    0.630 0.04259        0.552        0.720
 2297     60       1    0.620 0.04315        0.541        0.710
 2386     54       1    0.608 0.04385        0.528        0.701
 2400     53       1    0.597 0.04450        0.516        0.691
 2540     47       1    0.584 0.04533        0.502        0.680
 2583     42       1    0.570 0.04634        0.486        0.669
 2598     41       1    0.556 0.04725        0.471        0.657
 2689     38       1    0.542 0.04822        0.455        0.645
 3086     28       1    0.522 0.05023        0.433        0.631
 3222     24       1    0.501 0.05264        0.407        0.615
 3282     22       1    0.478 0.05495        0.381        0.599
 3574     18       1    0.451 0.05795        0.351        0.580
 3584     17       1    0.425 0.06032        0.322        0.561
 4079      8       1    0.372 0.07247        0.254        0.545
 4191      7       1    0.319 0.07922        0.196        0.519


par(mai=c(1,1,1,1))
plot(fit,main="KM Curve", xlab="Time(Week)", ylab=expression(paste(hat(S),"(t)")))

# Log rank test (difference between groups)
log_rank = survdiff(Surv(data$futime, data$status) ~ data$drug, data)
log_rank

결과를 보시면 플라시보와 페니실린 처방군간에 생존률에 큰 차이가 없는 것을 확인할 수 있습니다.


두 군간에 차이가 있는지 검정하는 방법인 log_rank 테스트에서도 p value > 0.05로 두 군간에 차이가 유의하지 않습니다.


Call:
survdiff(formula = Surv(data$futime, data$status) ~ data$drug, 
    data = data)

              N Observed Expected (O-E)^2/E (O-E)^2/V
data$drug=0 154       60     61.8    0.0513     0.102
data$drug=1 158       65     63.2    0.0502     0.102
 

Chisq= 0.1 on 1 degrees of freedom, p= 0.7



2. Cox regression


생존분석을 다변수로 할 때, Cox regression을 주로 활용합니다. 이는 Cox proportional hazard model로 불리기도 합니다.


Cox regression은 다음과 같은 이유로 많이 쓰입니다.


1. 다양한 변수들의 계수와 hazard ratio를 추정하는데 좋다. -> 이를 통해 변수별 생존에 대한 중요도를 비교하기 쉽다.

2. Cox regression은 robust 하다. (참에 매우 근접한 값을 추정해준다.)

3. 계산된 hazard가 양수이기 때문에 타당한 값이다.

4. baseline hazard를 몰라도 회귀계수, hazard ratio를 추정할 수 있다.


Cox regression의 이론적 배경에 대해서는 다음에 기회가 있을 때 다루어보도록 하겠습니다. 


R에서 Cox regression을 수행하는 것은 매우 간단한데, 앞서 정의한 event, time 변수인 Y를 종속변수로 놓고 분석대상인 변수들을 ~ +로 연결하면 됩니다.  

# Cox regression
cox = coxph(Y~data$drug + data$age + data$sex + data$stage + data$edema + data$bili + data$albumin)
summary(cox) 
Call:
coxph(formula = Y ~ data$drug + data$age + data$sex + data$stage + 
    data$edema + data$bili + data$albumin)

  n= 312, number of events= 125 

                   coef  exp(coef)   se(coef)      z Pr(>|z|)    
data$drug1    2.569e-02  1.026e+00  1.855e-01  0.138 0.889882    
data$age      6.736e-05  1.000e+00  2.651e-05  2.541 0.011057 *  
data$sex     -5.940e-01  5.521e-01  2.550e-01 -2.330 0.019832 *  
data$stage1  -2.248e+00  1.056e-01  1.023e+00 -2.197 0.027992 *  
data$stage2  -8.573e-01  4.243e-01  2.950e-01 -2.906 0.003659 ** 
data$stage3  -4.884e-01  6.136e-01  2.186e-01 -2.234 0.025487 *  
data$stage4          NA         NA  0.000e+00     NA       NA    
data$edema    9.740e-01  2.649e+00  3.148e-01  3.095 0.001971 ** 
data$bili     1.263e-01  1.135e+00  1.529e-02  8.263  < 2e-16 ***
data$albumin -9.288e-01  3.950e-01  2.556e-01 -3.634 0.000279 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

             exp(coef) exp(-coef) lower .95 upper .95
data$drug1      1.0260     0.9746   0.71322    1.4760
data$age        1.0001     0.9999   1.00002    1.0001
data$sex        0.5521     1.8112   0.33497    0.9101
data$stage1     0.1056     9.4656   0.01423    0.7844
data$stage2     0.4243     2.3568   0.23801    0.7564
data$stage3     0.6136     1.6296   0.39979    0.9419
data$stage4         NA         NA        NA        NA
data$edema      2.6486     0.3776   1.42921    4.9083
data$bili       1.1347     0.8813   1.10117    1.1692
data$albumin    0.3950     2.5315   0.23936    0.6519

Concordance= 0.839  (se = 0.029 )
Rsquare= 0.427   (max possible= 0.983 )
Likelihood ratio test= 174  on 9 df,   p=<2e-16
Wald test            = 186.2  on 9 df,   p=<2e-16
Score (logrank) test = 287  on 9 df,   p=<2e-16


그러면 이렇게 회귀계수와 회귀 계수의 exponential을 돌려주게 됩니다. Cox regression이 좋은 점은 회귀계수에 exponential을 취했을 때, 해당 변수가 1단위 증가했을 때의 hazard ratio가 됩니다. 예를 들어, age의 경우, 다른 변수들을 보정하고, 1살 증가했을 때, hazard가 1.0001배 증가한다. 라고 볼 수 있습니다. sex의 경우, 다른 모든 변수를 보정했을 때, 남자에 비해 여자가 hazard가 0.55 배라고 볼 수 있습니다 (이 데이터에서 0=male, 1=female로 코딩이 되어있기 때문에). p-value를 보면 어떠한 변수가 생존에 영향을 크게 끼치는 지를 비교해볼 수 있습니다.  



반응형

'Tools > R' 카테고리의 다른 글

R igraph 설치 오류 해결  (0) 2018.12.28
R Default library path 바꾸기  (2) 2018.12.28
Jupyter notebook에서 R을 이용하기 (IRkernel)  (6) 2018.10.05
R 패키지 설치시 gfortran 컴파일 오류  (0) 2018.07.06
R 유명한 패키지 정리  (0) 2018.03.19
반응형

Jupyter notebook 에서 R을 이용하기


데이터 분석을 할 때, PythonR을 동시에 이용하시는 분들이 많습니다.

저 같은 경우도 머신러닝, 딥러닝 등을 할 때는 Python을, 데이터 처리, 가공, 통계분석을 할 때는 R을 선호하는데요. 이 경우 Jupyter notebook 등의 Python 개발 환경과 R studio 를 번갈아가면서 이용해야해서 불편한 점이 많았습니다. 


본 포스팅에서는 Jupyter notebook이라는 하나의 개발 환경에서 R과 Python을 같이 이용할 수 있게 해주는 IRkernel을 설치하는 것을 포스팅해보았습니다.


IRkernel을 이용하면 Jupyter notebook에서도 현재 컴퓨터에 설치된 R 커널을 이용할 수 있게 해줍니다.

IRkernel은 R 커널을 Jupyter notebook에서 이용할 수 있게 해주는 패키지입니다. 

https://github.com/IRkernel/IRkernel


우선 당연히 선행적으로 Jupyter가 설치되어있어야하며,


주의할 점은 conda 가상환경 쓰시는 분들은

이걸 jupyter notebook이 설치된 conda 가상환경을 키고 IRkernel 설치를 진행하여야합니다.


먼저 devtools를 설치합니다.

install.packages('devtools')


다음 devtools를 이용해 IRkernel을 설치합니다.


devtools::install_github('IRkernel/IRkernel')

# or devtools::install_local('IRkernel-master.tar.gz')

IRkernel::installspec()  # to register the kernel in the current R installation



이렇게 R kernel이 생기게 됩니다.



저는 R version 3.5.1을 이용중이었는데 동일한 버전을 Jupyter notebook에서도 이용할 수 있습니다.


---- 추가 (2020-09-28)

conda install r-irkernel

위 conda 커맨드로 anaconda 가상환경 밑에 R 과 IRKernel 을 동시에 설치할 수도 있습니다. 


특정 R 버전에 설치하기 위해서는 아래 참고 (2020-10-16 추가)

http://salvatoregiorgi.com/blog/2018/10/16/installing-an-older-version-of-r-in-a-conda-environment/

반응형
반응형


문제

/usr/bin/x86_64-linux-gnu-ld: cannot find -lgfortran


Bioconductor를 통해 R 라이브러리를 설치할 때, 위와 같은 컴파일 오류로 인해 제대로 설치되지 않는 현상 발생



해결

https://askubuntu.com/questions/1007591/usr-bin-ld-cannot-find-lopencl


아래 위치에 gfortran 라이브러리가 없어서 문제 발생

/usr/lib/x86_64-linux-gnu/

아래 명령어로 문제 해결

sudo ln -s /usr/lib/x86_64-linux-gnu/libgfortran.so.3 /usr/lib/libgfortran.so

반응형
반응형

유명하고 많이 사용하는 R 패키지 정리

가장 유명하고, 많이 다운로드 되는 R 패키지들을 그 목적에 따라서 정리하였습니다. 본 포스트는 이 포스트를 참고하였습니다.

데이터 로드

RMySQL, RPostgresSQL, RSQLite - 데이터 베이스로부터 직접 데이터를 읽을 때 사용하는 패키지들이다. R[데이터베이스명] RMySQL은 MySQL의 데이터들을 직접 R로 불러올 수 있다.

XLConnect, xlsx - 이 패키지들은 Microsoft사의 엑셀을 R로부터 직접 읽어올 수 있게 한다. 물론, write도 가능하다.

foreign - SAS, SPSS 데이터셋을 읽어올 때 사용한다. 예를 들어, SAS의 경우 sas7bdat 확장자로 되어있는 파일인데, 이를 읽어올 때 foreign 패키지를 활용할 수 있다.


일반적인 텍스트 파일을 로드할 때, R에서는 별다른 패키지가 필요하지 않다. read.csv, read.table, read.fwf를 이용하면 된다. 이외의 독특한 자신만의 데이터셋을 불러오고 싶다면 CRAN guide에 데이터 import, export에 관하여 문의할 수도 있다. 

데이터 핸들링

dplyr - 데이터 subsetting, summarizing, rearranging, joining에 대한 더 쉬운 길을 제공한다. dplyr는 빠른 데이터 핸들링을 위하여 반드시 사용하는 패키지이다.(go to package) 

tidyr - 데이터셋의 레이아웃을 바꿀 때 유용한 툴이다. 데이터를 tidy format으로 바꾸기 위해 gather이나 spread 함수를 사용할 수 있다.

stringr - 문자열 다루는 것과 정규 표현식 관련 패키지이다. 

lubridate - date와 time을 더욱 다루기 쉽게 만드는 툴이다.

데이터 시각화

ggplot2 - R의 매우 유명한 시각화 패키지이다. grammar of graphics 를 활용하여 layered, customizable plot을 만들 수 있다는 장점이 있다.

ggvis grammar of graphics을 기반으로 동작하는, 대화형, 웹베이스의 그래픽 라이브러리이다.

rgl - Interactive 3D 시각화를 위한 라이브러리이다. 

htmlwidgets - 자바스크립트 기반의 interactive 시각화를 위한 툴이다. 이 패키지는 아래와 같은 htmlwidget들을 구현하고 있다.

googleVis - R에서 데이터 시각화를 위해 구글 차트를 이용할 수 있게한다. 구글 차트 툴은 Gapminder라고 불리기도 한다. 이는 시각화 소프트웨어로, Hans Rosling의 TED 출연으로 유명해졌다.


데이터 모델링

car - car 패키지의 Anova 함수는 type2, type3 아노바 테이블을 만드는데 유명하다.

mgcv - Generalized Additive Models

lme4/nlme - Linear, Non-linear 혼합효과모형

randomForest - 머신러닝의 랜덤 포레스트

multcomp - 다중비교를 위한 툴

vcd - 범주형 변수의 시각화와 분석을 위한 툴이다.

glmnet - Lasso, elastic-net 회귀분석을 cross validation과 함께 해준다.

survival - 생존분석

caret - 회귀분석 및 분류 모델의 트레이닝을 위한 툴이다.


데이터 리포트

shiny - 인터랙티브한 웹앱을 쉽게 만들어준다. 프로그래머가 아닌 일반 사람들에게 데이터 exploring과 sharing을 쉽게 만들어준다.

R Markdown - Reproducible reporting을 위한 툴이다. R 코드를  markdown 에 쓰고, render을 하면 R Markdown은 코드를 코드 실행 결과와 함께 HTML, pdf, word 형식으로 export를 해준다. 결과를 정리하는 다른 과정 없이 자동화된 리포팅을 알 수 있게 된다. R Markdown은 RStudio와 통합된다.

xtable - xtable 함수는 R Object(예를 들어, dataframe)를 통해 latex이나 HTML 코드로 리턴해준다. 이를 통해 문서에 붙여넣기를 쉽게할 수 있다. 

공간 데이터 

sp, maptools - shapefile을 비롯한 공간 데이터를 로딩할 수 있는 툴이다.

maps -  맵에 다각형을 쉽게 그려주는 툴이다.

ggmap -  Google map으로 부터 street map을 다운로드 받고, ggplot의 background로 쓸 수 있다.

시계열, 금융 데이터

zoo - 시계열 데이터를 저장하기 위한 가장 유명한 포맷을 다룰 수 있다.

xts - 시계열 데이터를 다루기 위한 툴

quantmod - 금융 데이터를 다운로드하고, 그래프를 그리고, 분석할 수 있는 툴이다.

높은 성능을 내기 위한 R 코드 작성

Rcpp - C++을 call하는 R function을 사용한다. 

data.table - 데이터셋을 빠르게 조작하기 위한 다른 방법을 사용한다. "빅 데이터"에 유용하다.

parallel - 큰 데이터 셋을 다루기 위한 병렬 프로세싱을 사용한다.

웹으로 작업하기

XML - R을 통해 XML 문서를 읽고 만드는 패키지

jsonlite - R을 통해 JSON 데이터를 읽고 만드는 패키지

httr - HTTP Connection을 통한 작업을 위한 라이브러리

R 패키지 만들기

devtools - 코드를 R 패키지로 만들기

testthat - 프로젝트의 유닛 테스트를 위한 쉬운 방법을 제공한다.

roxygen2 - R 패키지의 도큐먼트를 만들기 위한 빠른 방법. roxygen2는 코드의 코멘트를 도큐먼트로 만들고, 패키지의 네임스페이스를 만든다.


반응형
반응형

문자 변수를 날짜 변수로 변환하기


R에서 시계열 데이터를 다룰 때, 변수를 날짜 타입으로 변환한다면 플롯을 하는데 간편한 점이 많다. R의 날짜 데이터 타입으로는 "POSIXct" 가 있으며, as.POSIXct 함수를 통해 문자 변수를 POSIXct 타입으로 변환할 수 있다. 반대로 POSIXct 타입을 문자 타입으로 바꾸는 것은 format이나 as.character를 이용한다.  


# create POSIXct variables
as.POSIXct("080406 10:11", format = "%y%m%d %H:%M")
## [1] "2008-04-06 10:11:00 CDT"

as.POSIXct("2008-04-06 10:11:01 PM", format = "%Y-%m-%d %I:%M:%S %p")
## [1] "2008-04-06 22:11:01 CDT"

as.POSIXct("08/04/06 22:11:00", format = "%m/%d/%y %H:%M:%S")
## [1] "2006-08-04 22:11:00 CDT"
# convert POSIXct variables to character strings

format(as.POSIXct("080406 10:11", format = "%y%m%d %H:%M"), "%m/%d/%Y %I:%M %p")
## [1] "04/06/2008 10:11 AM"

as.character(as.POSIXct("080406 10:11", format = "%y%m%d %H:%M"), format = "%m-%d-%y %H:%M")
## [1] "04-06-08 10:11"


만약 어떤 dataframe의 column이 POSIXct 타입이라면, 내부적으로는 정수를 저장하고 있기 때문에 Plot을 할 때는 숫자 형태로 변환하여 데이터를 순차적으로 나타내준다. 



그래프 그리기


data <- read.csv("C:\\workspace\\r\\data\\data.csv")
plot(data$dateFormat, data$value)



이렇게 기본 내장함수인 plot을 사용해도 x축을 시간으로 하여 괜찮은 모양으로 그려주는 것을 확인할 수 있다. 만약 x축 값의 포맷을 지정하거나, 적절한 간격을 주고 싶다면 ggplot2 패키지를 이용하는 것도 좋다.


GGPLOT2 라이브러리를 통한 그래프 그리기


library(scales)

ggplot(data = data, aes(x = date, y = value)) + 
    geom_line(size=2) + ylim(0,1000) + xlab("Time") + ylab("㎍/㎥") + 
    scale_x_datetime(breaks = date_breaks("1 hour"), minor_breaks=date_breaks("1 hour"), labels=date_format("%H:%M"), limits=xlim) +
    ggtitle("title") + theme_bw() + theme(text = element_text(size = 25))


ggplot 명령어 설명 


aes : (x축, y축에 사용될 변수를 지정한다.)

geom_line : line plot. size 키워드를 통해 선의 굵기 지정

ylim : y축의 범위를 지정함

xlab : x축 label

ylab : y축 label

scale_x_datetime : x축의 간격, 포맷을 지정함. (library(scales) 이후에 사용할 수 있다.)

ggtitle : title 지정

theme_bw() : 해당 테마 지정 (black & white style)

theme : 그래프의 전반적인 속성을 지정한다. 위에서는 텍스트 사이즈를 25 조정함




특정 날짜 범위에 있는 데이터만 골라내기


아래 코드는 date가 2018/01/16 인 row만 골라서 subset으로 저장한다. 이처럼 format을 통해 POSIXct 데이터 타입을 character 타입으로 변환할 수 있다.


subset <- data[(format(data$date, "%m/%d/%Y") == "01/16/2018")]



참고

http://biostat.mc.vanderbilt.edu/wiki/pub/Main/ColeBeck/datestimes.pdf

반응형
반응형

R - 특정 버전의 패키지 설치하기


우선 패키지의 버전을 알아보는 방법은 R을 실행 시킨 후, 


library(package_name)

sessionInfo()


를 입력하면 패키지의 버전을 알 수 있다.


특정 버전의 R 패키지를 설치하는 방법은 우선, Install.packages("devtools")로 devtool을 설치한다.


require(devtools)
install_version("ggplot2", version = "0.9.1", repos = "http://cran.us.r-project.org")


위와 같은 방식으로 특정 버전의 CRAN 패키지를 설치할 수 있다. 이미 패키지가 설치된 상태에서도 install_version 을 활용하면 버전이 바뀌어 다시 설치되기 때문에, 패키지를 다운그레이드 시킬 때도 유용하게 쓸 수 있다.

반응형
반응형


R에서 csv 파일을 읽어들일 때 UTF-8 포맷의 텍스트 파일을 읽어오지 못하는 문제가 있었다.


temp <- read.table(path, sep=",", stringsAsFactors=FALSE, header=FALSE, nrows=10) head(temp)


  V1                                                        V2     V3 V4 V5 V6 V7 V8

1  4 01. 16. 18 \xec삤\xec쟾 08\xec떆 02遺\x84 25珥\x88,26.188 17.695 NA NA NA NA NA

2  5 01. 16. 18 \xec삤\xec쟾 08\xec떆 03遺\x84 25珥\x88,26.456 22.904 NA NA NA NA NA

3  6 01. 16. 18 \xec삤\xec쟾 08\xec떆 04遺\x84 25珥\x88,26.530 19.185 NA NA NA NA NA

4  7 01. 16. 18 \xec삤\xec쟾 08\xec떆 05遺\x84 25珥\x88,26.603 19.383 NA NA NA NA NA

5  8 01. 16. 18 \xec삤\xec쟾 08\xec떆 06遺\x84 25珥\x88,26.676 21.714 NA NA NA NA NA

6  9 01. 16. 18 \xec삤\xec쟾 08\xec떆 07遺\x84 25珥\x88,26.652 21.107 NA NA NA NA NA


위와 같이 파일이 깨지는 현상


temp <- read.table(path, sep=",", stringsAsFactors=FALSE, header=FALSE, nrows=10,fileEncoding = "utf-8")


Error in read.table(paste0(path, date, name, filename_hobo), skip = 5,  : 

  입력에 가능한 라인들이 없습니다

In addition: Warning messages:

1: In readLines(file, skip) :

  invalid input found on input connection 'C:\workspace\r\data\mongol\180116\1\MG2018_0116_KSY_HOBO.csv'

2: In readLines(file, skip) :

  incomplete final line found on 'C:\workspace\r\data\mongol\180116\1\MG2018_0116_KSY_HOBO.csv'


fileEncoding="utf-8" 옵션을 넣으면 아예 읽어들이지도 못한다.

해법을 찾다가 포기하고 결국 간접적인 해법으로 다음과 같은 리눅스 쉘 스크립트를 통해 utf-8을 모두 euc-kr로 바꾸고 r에서 읽었다.

find . -name '*.csv' -exec iconv -f utf-8 -t euc-kr "{}" -o "{}" -c \;

이 명령어는 현재 디렉토리 아래에 있는 모든 csv 파일의 인코딩을 utf-8에서 euc-kr로 바꾼다. 


이후에 읽으니까 파일 읽기에 성공하였다.

반응형
반응형

R - 종속변수가 순서 척도인 로지스틱 회귀분석


다항 로지스틱 회귀분석에서 종속변수가 명목형이 아닌 순서형인 경우 분석하는 방법에 관한 포스팅입니다. 이 포스팅은 이 사이트의 튜토리얼을 보고 작성하였습니다.


라이브러리 로드

require(foreign)
require(ggplot2)
require(MASS)
require(Hmisc)
require(reshape2)


데이터 읽기

dat <- read.dta("https://stats.idre.ucla.edu/stat/data/ologit.dta")
head(dat)
> head(dat)
            apply pared public  gpa
1     very likely     0      0 3.26
2 somewhat likely     1      0 3.21
3        unlikely     1      1 3.94
4 somewhat likely     0      0 2.81
5 somewhat likely     0      0 2.53
6        unlikely     0      1 2.59


X : pared(부모중 한명이 대학 학위가 있는지 여부), public(졸업한 학교가 공립인지), gpa(학점)

Y : apply (“unlikely”, “somewhat likely”, “very likely”, 각각 1, 2, 3으로 코딩되어있음) => 대학원에 진학할 가능성


이 때 Y는 순서형 척도이다.


범주형 변수의 빈도 확인


lapply 함수를 이용해 범주형 변수의 빈도표를 확인

## one at a time, table apply, pared, and public
lapply(dat[, c("apply", "pared", "public")], table)
> lapply(dat[, c("apply", "pared", "public")], table)
$apply

       unlikely somewhat likely     very likely 
            220             140              40 

$pared

  0   1 
337  63 

$public

  0   1 
343  57 

범주형 독립변수와 종속변수 관계 파악 : 3-변수 빈도표


변수 빈도표를 통해 로지스틱 회귀분석을 하기에 앞서 예상되는 결과를 미리 확인한다.

## three way cross tabs (xtabs) and flatten the table
ftable(xtabs(~ public + apply + pared, data = dat))
> ftable(xtabs(~ public + apply + pared, data = dat))
                       pared   0   1
public apply                        
0      unlikely              175  14
       somewhat likely        98  26
       very likely            20  10
1      unlikely               25   6
       somewhat likely        12   4
       very likely             7   3



연속형 변수 분포 확인

summary(dat$gpa)
> summary(dat$gpa)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  1.900   2.720   2.990   2.999   3.270   4.000 
sd(dat$gpa)
> sd(dat$gpa)
[1] 0.3979409


연속형 독립 변수와 종속 변수와의 관계 파악


Apply에 따라 gpa가 어떻게 분포하여있는지 상자그림을 통해 확인한다. 이러한 경향을 수치화하는 것이 로지스틱 회귀분석의 목표이다.

ggplot(dat, aes(x = apply, y = gpa)) +
  geom_boxplot(size = .75) +
  geom_jitter(alpha = .5) +
  facet_grid(pared ~ public, margins = TRUE) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1))

지금까지는 데이터에 대해서 살펴보았고, 본격적으로 순서 척도가 종속변수인 로지스틱 회귀분석을 어떻게 하는지 알아본다.


이 때 가능한 분석방법은 꼭 순서형 척도만은 아닐 것이다. GPA만을 독립변수로하여 ANOVA를 할 수도 있고, y를 1,2,3으로 놓고 다중회귀분석을 할 수도 있다. 또 y를 순서가 없는 명목형 척도로 보고 명목형 다항 로지스틱 분석(multinomial logistic regression)을 할 수도 있을 것이다. 하지만 해당 데이터에 대해 위 분석 방법들은 가정에 맞지 않는다. 따라서 순서형 척도를 종속변수로하는 로지스틱 회귀분석(ordinal logistic regression)이 적합하다.


순서형 척도를 종속변수로하는 로지스틱 회귀분석의 중요한 가정은 회귀계수가 같다고 가정하는 것이다. y=1,2,3인 이  데이터의 경우 어떠한 변수의 변화가 1 vs 2,3의 OR에 미치는 영향과 1,2 vs 3의 OR에 미치는 영향이 같다고 가정한다. y의 범주가 3개인 경우 2개의 식이 나오면 이 두식은 회귀계수가 같고, 단지 절편만 다르다.


MASS 패키지의 polr 함수를(proportional odds logistic regession) 이용하여 순서형 변수를 종속변수로하는 다항 로지스틱 회귀분석을 해보자.


회귀식을 적어주고 summary를 통해 적합된 결과를 본다. Hess=TRUE는 optimization을 할 때 사용하는 Hessian matrix를 의미한다. (https://en.wikipedia.org/wiki/Hessian_matrix)

## fit ordered logit model and store results 'm'
m <- polr(apply ~ pared + public + gpa, data = dat, Hess=TRUE)

## view a summary of the model
summary(m)
> summary(m)
Call:
polr(formula = apply ~ pared + public + gpa, data = dat, Hess = TRUE)

Coefficients:
          Value Std. Error t value
pared   1.04769     0.2658  3.9418
public -0.05879     0.2979 -0.1974
gpa     0.61594     0.2606  2.3632

Intercepts:
                            Value   Std. Error t value
unlikely|somewhat likely     2.2039  0.7795     2.8272
somewhat likely|very likely  4.2994  0.8043     5.3453

Residual Deviance: 717.0249 
AIC: 727.0249 


결과 해석


회귀계수에 exponential을 취하면 OR(Odds ratio)이 되며 이를 통해 결과를 해석해본다.

## odds ratios
exp(coef(m))
> exp(coef(m))
    pared    public       gpa 
2.8510579 0.9429088 1.8513972 


순서척도 로지스틱 회귀분석에서 OR은 proportional OR이라고도 부른다.


  • 다른 변수가 고정되어있을 때, pared=0일 때에 비하여 pared=1일 때, “very likely” vs “somewhat likely” or “unlikely”의 OR이 2.851이다.
  • 다른 변수가 고정되어있을 때, pared=0일 때에 비하여 pared=1일 때, “very likely” or “somewhat likely” vs “unlikely”의 OR이 2.851이다.
  • 이는 즉, pared=1일 때, 대학원 진학(apply)을 할 가능성이 높다는 것을 뜻한다.
  • 같은 binary 변수인 public도 위와 마찬가지로 해석한다.
  • 다른 변수가 고정되어있을 때, gpa가 1 증가할 때, “very likely” vs “somewhat likely” or “unlikely” Odds가 1.85배가 된다.
  • 다른 변수가 고정되어있을 때, gpa가 1 증가할 때, “very likely” or “somewhat likely” vs “unlikely” Odds가 1.85배가 된다.


이를 식으로 표현하면


log Odds(Y=very) = 2.2039 + 1.04pared - 0.05879public + 0.61594gpa

log Odds(Y=very or somewhat) = 4.2994 + 1.04pared - 0.05879public + 0.61594gpa


  • 이 때, Odds(Y=1) = P(P1/(1-P1)), Odds(Y=1,2) = P((P1+P2)/(1-P1-P2))
  • log Odds 는 logit function 이라고도 부른다.


위 두 방정식을 풀면 P(Y=1), P(Y=2), P(Y=3) 3개의 식을 얻을 수 있다. 이 식은 X가 주어졌을 때, Y의 예측값을 구한다.


반응형
반응형


R - Multinomial Logistic Regression


Multinomial Logistic Regression이란 y의 범주가 3개 이상(multi)이며 명목형(nomial)일 때 사용하는 로지스틱 회귀분석이다. 본 포스팅은 이 사이트의 튜토리얼을 보고 실습하고 해석한 자료이다.


데이터 설명


해당 데이터셋은 hsbdemo 데이터셋으로 총 n은 200이다.

ml <- read.dta("https://stats.idre.ucla.edu/stat/data/hsbdemo.dta")

> head(ml)
   id female    ses schtyp     prog read write math science socst       honors awards cid
1  45 female    low public vocation   34    35   41      29    26 not enrolled      0   1
2 108   male middle public  general   34    33   41      36    36 not enrolled      0   1
3  15   male   high public vocation   39    39   44      26    42 not enrolled      0   1
4  67   male    low public vocation   37    37   42      33    32 not enrolled      0   1
5 153   male middle public vocation   39    31   40      39    51 not enrolled      0   1
6  51 female   high public  general   42    36   42      31    39 not enrolled      0   1

Y : prog (프로그램 타입)

X : ses(social economic status), write (writing score)


다중회귀분석을 통해 X가 Y에 어떤 영향을 미치는지 알아본다.


빈도 테이블과 그룹 평균을 통해 X와 Y의 관계 알아보기

with(ml, table(ses, prog)) 
# 또는 table(ml$ses, ml$prog) 
# 또는 xtabs(~ses+prog, data=ml)

> with(ml, table(ses, prog)) prog ses general academic vocation low 16 19 12 middle 20 44 31 high 9 42 7

with(ml, do.call(rbind, tapply(write, prog, function(x) c(M = mean(x), SD = sd(x)))))

> with(ml, do.call(rbind, tapply(write, prog, function(x) c(M = mean(x), SD = sd(x))))) M SD general 51.33333 9.397775 academic 56.25714 7.943343 vocation 46.76000 9.318754

nnet 패키지의 multinom 함수를 통해 다중 로지스틱 회귀분석 실시

ml$prog2 <- relevel(ml$prog, ref = "academic")
test <- multinom(prog2 ~ ses + write, data = ml)

multinom을 실행하기 전에 relevel이라는 함수를 통해 reference를 지정해준다. 이 reference를 기준으로 결과를 해석할 수 있다. 따라서 이 reference는 어떤 baseline이 되어야한다. 이 경우에 academic이 baseline이며 이를 기준으로 하여 분석한다.

multinom 함수를 실행하면 모델이 fitting되어 계수가 결정되고 이 정보는 test에 담긴다.


summary(test)
> summary(test)
Call:
multinom(formula = prog2 ~ ses + write, data = ml)

Coefficients:
         (Intercept)  sesmiddle    seshigh      write
general     2.852198 -0.5332810 -1.1628226 -0.0579287
vocation    5.218260  0.2913859 -0.9826649 -0.1136037

Std. Errors:
         (Intercept) sesmiddle   seshigh      write
general     1.166441 0.4437323 0.5142196 0.02141097
vocation    1.163552 0.4763739 0.5955665 0.02221996

Residual Deviance: 359.9635 
AIC: 375.9635 

 


이 예제의 경우 다중 로지스틱 회귀분석의 계수는 2세트가 나오게 된다.

 

1. academic vs general 의 log odds에 관한 계수

2. academic vs vocation의 log odds에 관한 계수


결과 해석


  • write가 1단위 증가할 때, academic이 general이 될 log odds가 -0.058이 된다.
  • write가 1단위 증가할 때, academic이 vocation이 될 log odds가 -0.1136037이 된다.
  • ses:row에서 ses:high로 변할 때, academic이 general이 될 log odds가 -1.1628이 된다.
  • ses:row에서 ses:middle로 변할 때, academic이 general이 될 log odds가 -0.5332가 된다.
  • ses:row에서 ses:high로 변할 때, academic이 vocation이 될 log odds가 -0.9826이 된다.
  • ses:row에서 ses:middle로 변할 때, academic이 vocation이 될 log odds가 +0.29가 된다.


변수의 유의성 판단

coefficient가 0라는 귀무가설 하에서 coef ~ N(0, sd^2)라는걸 이용하여 z-test 한다.

z <- summary(test)$coefficients/summary(test)$standard.errors
z
> z <- summary(test)$coefficients/summary(test)$standard.errors
> z
         (Intercept)  sesmiddle   seshigh     write
general     2.445214 -1.2018081 -2.261334 -2.705562
vocation    4.484769  0.6116747 -1.649967 -5.112689
# 2-tailed z test
p <- (1 - pnorm(abs(z), 0, 1)) * 2
p
> p <- (1 - pnorm(abs(z), 0, 1)) * 2
> p
          (Intercept) sesmiddle    seshigh        write
general  0.0144766100 0.2294379 0.02373856 6.818902e-03
vocation 0.0000072993 0.5407530 0.09894976 3.176045e-07

OR 추정값

exp(coef(test))
> exp(coef(test))
         (Intercept) sesmiddle   seshigh     write
general     17.32582 0.5866769 0.3126026 0.9437172
vocation   184.61262 1.3382809 0.3743123 0.8926116

회귀 계수들에 exponential을 취하면, 이는 OR에 대한 추정값이 된다.


Write가 평균일 때, ses에 따라 예측값이 어떻게 달라지는가?

dses <- data.frame(ses = c("low", "middle", "high"), write = mean(ml$write))
dses
predict(test, newdata = dses, "probs")
> dses <- data.frame(ses = c("low", "middle", "high"), write = mean(ml$write))
> dses
     ses  write
1    low 52.775
2 middle 52.775
3   high 52.775

> predict(test, newdata = dses, "probs") academic general vocation 1 0.4396845 0.3581917 0.2021238 2 0.4777488 0.2283353 0.2939159 3 0.7009007 0.1784939 0.1206054

Write를 변화시켜가면서 예측값의 변화 관찰하기

dwrite <- data.frame(ses = rep(c("low", "middle", "high"), each = 41), write = rep(c(30:70),
                                                                                   3))

## store the predicted probabilities for each value of ses and write
pp.write <- cbind(dwrite, predict(test, newdata = dwrite, type = "probs", se = TRUE))

## calculate the mean probabilities within each level of ses
by(pp.write[, 3:5], pp.write$ses, colMeans)

## melt data set to long for ggplot2
lpp <- melt(pp.write, id.vars = c("ses", "write"), value.name = "probability")
head(lpp)  # view first few rows
> head(lpp)  # view first few rows
  ses write variable probability
1 low    30 academic  0.09843588
2 low    31 academic  0.10716868
3 low    32 academic  0.11650390
4 low    33 academic  0.12645834
5 low    34 academic  0.13704576
6 low    35 academic  0.14827643
## plot predicted probabilities across write values for each level of ses
## facetted by program type
ggplot(lpp, aes(x = write, y = probability, colour = ses)) + geom_line() + facet_grid(variable ~
                                                                                        ., scales = "free")
  • 이 그래프는 식을 전개하여 y를 sigmoid 함수 형태로 만든 것이다. 2개의 적합식에서 3개의 함수를 만들어낼 수 있다.


 

 

 Y~write의 결과랑 무엇이 다른가?


예측의 관점에서 보면 ses를 빼고 write만을 통해 Y를 예측하면 예측을 세분화하지 못하여 예측력이 떨어진다고 볼 수 있다. 이는 ses를 고려하지 않고, write와 Y의 관계만을 보기 때문이다. 따라서 ses가 추가됨으로써 write의 계수가 바뀐다는 것을 알 수 있다. 이 과정을 ses를 보정한다고도 말한다.

 

 

출처 - https://stats.idre.ucla.edu/r/dae/multinomial-logistic-regression/


반응형
반응형