factor level 수정 melt (reshape시 발생하는 문제 해결)



data frame에서 각각의 column의 factor level을 확장하는 방법


DF[2:3] <- lapply(DF[2:3], factor, levels=letters)
melt(DF, id.vars="id", factorsAsStrings=F)$value
[1] a b c z y x
Levels: a b c d e f g h i j k l m n o p q r s t u v w x y z

If however we reset the factors to have the same levels and only then melt:

DF[2:3] <- lapply(DF[2:3], factor, levels=letters)
melt(DF, id.vars="id", factorsAsStrings=F)$value


Assert 

# Assert 개발 -- 위코드에 추가함 

assert("A Poisson random number is non-negative", {

  x = rpois(1, 10)

  (x >= 11)

  (x > -1)  # () is optional because it's the last expression

})



'AI > R Basic' 카테고리의 다른 글

R Studio Server Install in Ubuntu Server  (3) 2018.07.04
Jupyter Notebook으로 R 실행  (2) 2018.04.15
Data Transformation: dplyr package  (0) 2018.04.14
두 개 데이터 프레임 병합, 빼기  (0) 2018.03.04
R Factor 검색  (0) 2017.11.13

R Studio Server Install in Ubuntu Server


Ubuntu Server 환경에 RStudio server를 설치하는 방법을 다룬다.

sudo apt-get --assume-yes update
sudo apt-get --assume-yes install r-base
sudo apt-get --assume-yes install gdebi-core

wget으로 버전에 맞는 RStudio deb 페키지 다운로드

공식사이트

$ wget https://download2.rstudio.org/rstudio-server-1.1.453-amd64.deb

Debian package로 설치하기

sudo gdebi --non-interactive rstudio-server-1.1.453-amd64.deb
Reading package lists... Done
Building dependency tree
Reading state information... Done
Reading state information... Done
Selecting previously unselected package rstudio-server.
(데이터베이스 읽는중 ...현재 80134개의 파일과 디렉터리가 설치되어 있습니다.)
Preparing to unpack rstudio-server-1.1.453-amd64.deb ...
Unpacking rstudio-server (1.1.453) ...
rstudio-server (1.1.453) 설정하는 중입니다 ...
groupadd: group 'rstudio-server' already exists
rsession: no process found
Created symlink from /etc/systemd/system/multi-user.target.wants/rstudio-server.service to /etc/systemd/system/rstudio-server.service.
● rstudio-server.service - RStudio Server
   Loaded: loaded (/etc/systemd/system/rstudio-server.service; enabled; vendor preset: enabled)
   Active: active (running) since 수 2018-07-04 19:06:22 KST; 1s ago
  Process: 5096 ExecStart=/usr/lib/rstudio-server/bin/rserver (code=exited, status=0/SUCCESS)
 Main PID: 5100 (rserver)
    Tasks: 3
   Memory: 1.2M
      CPU: 618ms
   CGroup: /system.slice/rstudio-server.service
           └─5100 /usr/lib/rstudio-server/bin/rserver

 7월 04 19:06:22 ubuntu systemd[1]: Starting RStudio Server...
 7월 04 19:06:22 ubuntu systemd[1]: Started RStudio Server.

Jupyter Notebook으로 R 실행


Anaconda 설치

Jupyter Notebook update

conda update ipython-notebook

IRkernel 설치

conda install -c r ipython-notebook r-irkernel

Rkernel을 jupyter에서 실행하기 위한 필수 package설치
아래의 명령어는 R console에서 실행 한다.

install.packages(c('rzmq','repr','IRkernel','IRdisplay'), repos = 'http://irkernel.github.io/', type = 'source')

모두 설치 후 R Console에서 다음을 입력한다.

IRkernel::installspec()
quit() # 종료

아래와 같이 R kernel이 생성 되었다.


Data Transformation: dplyr package


R의 신 Hadley Wickham의 책 R for Data Science 5장에 나오는 내용을 정리 한다.

Hadley Wickham본인이 직접 만든 패키지이므로 유용하다.
기타 그가 만든 패키지는 아래와 같다.

  • ggplot2
  • plyr
  • reshape2

plyr은 모든 함수가 R로 작성되어서 처리 속도가 느리다는 단점이 있다.
dplyr C++로 작성되어 불필요한 함수를 불러오지 않기 때문에 매우 빠른 처리 속도를 자랑한다.
결국 분할(split),적용(apply) 병합(combine)을 plyr로 하던것을 dplyr로 변경하는 패러다임 전환이다.

필자도 plyr {}{}ply를 많이 사용 했었다. 하지만 파이프연산과 조합한dplyr이 좀 더 가독성이 높고
속도도 빠르다고하니 이쪽으로 옴겨 가야 하는 것 같다.

dplyr의 지원 함수군 외의 특징

  • data.table 지원
  • 각종 DB지원: MySQL, PostgreSQL, SQLite, BigQuery
  • 데이터 큐브
함수명내용유사함수
filter()지정한 조건식에 맞는 데이터 추출subset()
select()열의 추출data[, c(“Year”, “Month”)]
mutate()열 추가transform()
arrange()정렬order(), sort()
summarise()집계aggregate()

필요 package

install.packages("nycflights13")
library("nycflights13")
library(tidyverse)

tidyverse 로딩시 아래와 같이 conflict메시지가 나올 수도 있다.

-- Attaching packages --------------------------------------- tidyverse 1.2.1 --
√ ggplot2 2.2.1     √ purrr   0.2.4
√ tibble  1.4.1     √ dplyr   0.7.4
√ tidyr   0.7.2     √ stringr 1.2.0
√ readr   1.1.1     √ forcats 0.3.0
-- Conflicts ------------------------------------------ tidyverse_conflicts() --
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()

flights데이터를 출력하면 아래와 같이 출력 된다.

> flights
# A tibble: 336,776 x 19
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time arr_delay carrier flight tailnum origin dest  air_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>     <dbl> <chr>    <int> <chr>   <chr>  <chr>    <dbl>
 1  2013     1     1      517            515      2.00      830            819     11.0  UA        1545 N14228  EWR    IAH      227  
 2  2013     1     1      533            529      4.00      850            830     20.0  UA        1714 N24211  LGA    IAH      227  
 3  2013     1     1      542            540      2.00      923            850     33.0  AA        1141 N619AA  JFK    MIA      160  
 4  2013     1     1      544            545     -1.00     1004           1022    -18.0  B6         725 N804JB  JFK    BQN      183  
 5  2013     1     1      554            600     -6.00      812            837    -25.0  DL         461 N668DN  LGA    ATL      116  
 6  2013     1     1      554            558     -4.00      740            728     12.0  UA        1696 N39463  EWR    ORD      150  
 7  2013     1     1      555            600     -5.00      913            854     19.0  B6         507 N516JB  EWR    FLL      158  
 8  2013     1     1      557            600     -3.00      709            723    -14.0  EV        5708 N829AS  LGA    IAD       53.0
 9  2013     1     1      557            600     -3.00      838            846    - 8.00 B6          79 N593JB  JFK    MCO      140  
10  2013     1     1      558            600     -2.00      753            745      8.00 AA         301 N3ALAA  LGA    ORD      138  
# ... with 336,766 more rows, and 4 more variables: distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dttm>
> class(flights)
[1] "tbl_df"     "tbl"        "data.frame"

336,776의 뉴욕에서 2013에 출발한 비행 정보를 담고 있다.
US Bureau of Transportation Statistics

tibble이라는 data.frame을 약간 변형 시킨것을 사용한다.
tibble에 대한 상세한 내용의 링크이다.

dplyr basics

중요 package 5개를 설명한다.

  • Pick obervations by their values (filter())
  • Reorder the rows (arrange())
  • Pick variables by their names(select())
  • Create new variables with functions of existing variables (mutate())
  • Collpase many values down to a single summary (summarise())

추가로 group_by()를 통해서 scope을 조절 할 수 있다.

filter()

관찰한 데이터의 subset을 쉽게 구할 수 있도록 해준다.
첫 번째 인자는 data frame이고, 아래 예제에서 그 다음 인자들은 조건을 의미한다.
아래의 예제는 January 1st를 필터링한 예제이다.

nov_dec <- filter(flights, month %in% c(11, 12))
# A tibble: 55,403 x 19
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time arr_delay carrier flight tailnum origin dest  air_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>     <dbl> <chr>    <int> <chr>   <chr>  <chr>    <dbl>
 1  2013    11     1        5           2359      6.00      352            345      7.00 B6         745 N568JB  JFK    PSE      205  
 2  2013    11     1       35           2250    105         123           2356     87.0  B6        1816 N353JB  JFK    SYR       36.0
 3  2013    11     1      455            500   -  5.00      641            651    -10.0  US        1895 N192UW  EWR    CLT       88.0
 4  2013    11     1      539            545   -  6.00      856            827     29.0  UA        1714 N38727  LGA    IAH      229  
 5  2013    11     1      542            545   -  3.00      831            855    -24.0  AA        2243 N5CLAA  JFK    MIA      147  
 6  2013    11     1      549            600   - 11.0       912            923    -11.0  UA         303 N595UA  JFK    SFO      359  
 7  2013    11     1      550            600   - 10.0       705            659      6.00 US        2167 N748UW  LGA    DCA       57.0
 8  2013    11     1      554            600   -  6.00      659            701    - 2.00 US        2134 N742PS  LGA    BOS       40.0
 9  2013    11     1      554            600   -  6.00      826            827    - 1.00 DL         563 N912DE  LGA    ATL      126  
10  2013    11     1      554            600   -  6.00      749            751    - 2.00 DL         731 N315NB  LGA    DTW       93.0
# ... with 55,393 more rows, and 4 more variables: distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dttm>

arrange()

정렬 용도

arrange(flights, desc(arr_delay))
#> # A tibble: 336,776 × 19
#>    year month   day dep_time sched_dep_time dep_delay arr_time
#>   <int> <int> <int>    <int>          <int>     <dbl>    <int>
#> 1  2013     1     9      641            900      1301     1242
#> 2  2013     6    15     1432           1935      1137     1607
#> 3  2013     1    10     1121           1635      1126     1239
#> 4  2013     9    20     1139           1845      1014     1457
#> 5  2013     7    22      845           1600      1005     1044
#> 6  2013     4    10     1100           1900       960     1342
#> # ... with 3.368e+05 more rows, and 12 more variables:
#> #   sched_arr_time <int>, arr_delay <dbl>, carrier <chr>, flight <int>,
#> #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>,
#> #   distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dttm>

select()

선택 용도

select(flights, year, month, day)
select(flights, year:day)
select(flights, -(year:day))
  • starts_with(“abc”): matches names that begin with “abc”.
  • ends_with(“xyz”): matches names that end with “xyz”.
  • contains(“ijk”): matches names that contain “ijk”.
  • matches(“(.)\1”): selects variables that match a regular expression. This one matches any variables that contain - repeated characters. You’ll learn more about regular expressions in strings.
  • num_range(“x”, 1:3) matches x1, x2 and x3.

mutate()

현재 있는 Data.Frame의 맨 뒤에다가 새로운 컬럼을 추가하는 것이다.

flights_sml <- select(flights, 
  year:day, 
  ends_with("delay"), 
  distance, 
  air_time
)
mutate(flights_sml,
  gain = arr_delay - dep_delay,
  speed = distance / air_time * 60
)
# A tibble: 336,776 x 9
    year month   day dep_delay arr_delay distance air_time   gain speed
   <int> <int> <int>     <dbl>     <dbl>    <dbl>    <dbl>  <dbl> <dbl>
 1  2013     1     1      2.00     11.0      1400    227     9.00   370
 2  2013     1     1      4.00     20.0      1416    227    16.0    374
 3  2013     1     1      2.00     33.0      1089    160    31.0    408
 4  2013     1     1     -1.00    -18.0      1576    183   -17.0    517
 5  2013     1     1     -6.00    -25.0       762    116   -19.0    394
 6  2013     1     1     -4.00     12.0       719    150    16.0    288
 7  2013     1     1     -5.00     19.0      1065    158    24.0    404
 8  2013     1     1     -3.00    -14.0       229     53.0 -11.0    259
 9  2013     1     1     -3.00    - 8.00      944    140   - 5.00   405
10  2013     1     1     -2.00      8.00      733    138    10.0    319
# ... with 336,766 more rows

plyr:transform과 다른점은 연이어서 생성한 컬럼을 바로 사용해도 된다는 것이다.

mutate(flights_sml,
  gain = arr_delay - dep_delay,
  hours = air_time / 60,
  gain_per_hour = gain / hours
)
# A tibble: 336,776 x 10
    year month   day dep_delay arr_delay distance air_time
   <int> <int> <int>     <dbl>     <dbl>    <dbl>    <dbl>
 1  2013     1     1      2.00     11.0      1400    227  
 2  2013     1     1      4.00     20.0      1416    227  
 3  2013     1     1      2.00     33.0      1089    160  
 4  2013     1     1     -1.00    -18.0      1576    183  
 5  2013     1     1     -6.00    -25.0       762    116  
 6  2013     1     1     -4.00     12.0       719    150  
 7  2013     1     1     -5.00     19.0      1065    158  
 8  2013     1     1     -3.00    -14.0       229     53.0
 9  2013     1     1     -3.00    - 8.00      944    140  
10  2013     1     1     -2.00      8.00      733    138  
# ... with 336,766 more rows, and 3 more variables: gain <dbl>,
#   hours <dbl>, gain_per_hour <dbl>

새로 생성한 variable columns만 유지하고 싶으면 transmute를 사용한다.

transmute(flights,
  gain = arr_delay - dep_delay,
  hours = air_time / 60,
  gain_per_hour = gain / hours
)
# A tibble: 336,776 x 3
     gain hours gain_per_hour
    <dbl> <dbl>         <dbl>
 1   9.00 3.78           2.38
 2  16.0  3.78           4.23
 3  31.0  2.67          11.6 
 4 -17.0  3.05         - 5.57
 5 -19.0  1.93         - 9.83
 6  16.0  2.50           6.40
 7  24.0  2.63           9.11
 8 -11.0  0.883        -12.5 
 9 - 5.00 2.33         - 2.14
10  10.0  2.30           4.35
# ... with 336,766 more rows

summarise()

그룹핑해서 하나의 single row로 합치는 역할을 한다.
그냥 summarise만 단독해서 사용하면 엄청나게 유용하진 않지만, group_by와 함께 사용하면 그 위력이 증대된다.

그냥 summarise하면 단 하나의 row로 처리됨

summarise(flights, delay = mean(dep_delay, na.rm = TRUE))
# A tibble: 1 x 1
  delay
  <dbl>
1  12.6

group_by를 이용해서 그룹핑 가능함

by_day <- group_by(flights, year, month, day)
summarise(by_day, delay = mean(dep_delay, na.rm = TRUE))
# pipe
group_by(flights, year, month, day) %>% summarise(delay = mean(dep_delay, na.rm = TRUE))
# A tibble: 365 x 4
# Groups:   year, month [?]
    year month   day delay
   <int> <int> <int> <dbl>
 1  2013     1     1 11.5 
 2  2013     1     2 13.9 
 3  2013     1     3 11.0 
 4  2013     1     4  8.95
 5  2013     1     5  5.73
 6  2013     1     6  7.15
 7  2013     1     7  5.42
 8  2013     1     8  2.55
 9  2013     1     9  2.28
10  2013     1    10  2.84
# ... with 355 more rows

파이프의 사용

아래 세개의 작업을 수행

  • flight를 destination에 따라서 그룹핑함
  • flight의 수와 거리, 평균 딜레이를 요약
  • Honolulu airport와 noisy point를 제거 한다.

파이를 사용하면 쓸 때 없는 중간 변수들을 정의하지 않아도 되기 때문에 편리하고 직관적인 이해를 달성한다.

파이프 사용

delays <- flights %>% 
  group_by(dest) %>% 
  summarise(
    count = n(),
    dist = mean(distance, na.rm = TRUE),
    delay = mean(arr_delay, na.rm = TRUE)
  ) %>% 
  filter(count > 20, dest != "HNL")

파이프 미사용

# Combining multiple operations with the pipe
by_dest <- group_by(flights, dest)
delay <- summarise(by_dest,
   count = n(),
   dist = mean(distance, na.rm = TRUE),
   delay = mean(arr_delay, na.rm = TRUE)
)
delay <- filter(delay, count > 20, dest != "HNL")

참고자료

R 데이터 처리의 새로운 강자, dplyr 패키지
dplyr로 데이터 집계와 분석


'AI > R Basic' 카테고리의 다른 글

R Studio Server Install in Ubuntu Server  (3) 2018.07.04
Jupyter Notebook으로 R 실행  (2) 2018.04.15
두 개 데이터 프레임 병합, 빼기  (0) 2018.03.04
R Factor 검색  (0) 2017.11.13
RStudio v1.1 Released  (0) 2017.10.10

두 개 데이터 프레임 병합, 빼기


공통 키를 기준으로 병합

하나이상의 key를 가지고 두 개의 데이터 프레임을 join하는 연산

# merge two data frames by ID
total <- merge(data frameA,data frameB,by="ID")

두 개의 데이터로 병합

# merge two data frames by ID and Country
total <- merge(data frameA,data frameB,by=c("ID","Country"))

빼기

Larger - Smaller

small

     ID       CSF1PO CSF1PO.1 D10S1248 D10S1248.1 D12S391 D12S391.1
203079_BA_M     10       11       14         16      -9        -9
203079_BA_F      8       12       14         17      -9        -9
203080_BA_M     10       12       13         13      -9        -9

big

      ID      CSF1PO CSF1PO.1 D10S1248 D10S1248.1 D12S391 D12S391.1
203078_MG_M     -9       -9       15         15      18        20
203078_MG_F     -9       -9       14         15      17        19
203079_BA_M     10       11       14         16      -9        -9
203079_BA_F      8       12       14         17      -9        -9
203080_BA_M     10       12       13         13      -9        -9
203080_BA_F     10       11       14         16      -9        -9
203081_MG_M     10       12       14         16      -9        -9
203081_MG_F     11       12       15         16      -9        -9
203082_MG_M     11       11       13         15      -9        -9
203082_MG_F     11       11       13         14      -9        -9

Solution

BigDF[ !(BigDF$ID %in% SmallDF$ID), ]

'AI > R Basic' 카테고리의 다른 글

Jupyter Notebook으로 R 실행  (2) 2018.04.15
Data Transformation: dplyr package  (0) 2018.04.14
R Factor 검색  (0) 2017.11.13
RStudio v1.1 Released  (0) 2017.10.10
rJava load 에러  (0) 2017.04.16

R Factor 검색


factor로 구성된 vector가 있다고 가정 한다.

%in

'a' %in% v

any()
any('a' == v)
[1] TRUE

is.element()
is.element('a',v)

첫 번째 매치 index 반환

match('a',v)

모든 일치하는 index 반환

which('a' == v)
[1] 2 4


'AI > R Basic' 카테고리의 다른 글

Data Transformation: dplyr package  (0) 2018.04.14
두 개 데이터 프레임 병합, 빼기  (0) 2018.03.04
RStudio v1.1 Released  (0) 2017.10.10
rJava load 에러  (0) 2017.04.16
Swapping columns in a matrix  (0) 2017.03.31

RStudio v1.1 Released


R Studio가 정식버전으로 2017-10-09일자로 v1.1이 업데이트 되었습니다.

위와 같이 Dark 테마가 기본으로 설정됩니다. 또한 terminal이 기본으로 탑제 되었습니다.

기타 변경사항의 Highlight는 아래와 같습니다.

  • connection tab: 다양한 database들과 쉽게 연결 하여 탐색 할 수 있습니다.
  • terminal tab: shell을 지원합니다.
  • object explorer: R data 구조와 객체를 좀 더 깊이 있게 탐색 할 수 있습니다.
  • dark theme: 현대적인 Theme을 사용 할 수 있습니다.
  • 다양한 약간의 향상과 버그 수정

Pro version은 좀 더 다양한 기능을 제공 받습니다.

설치 방법

  1. 공식사이트 URL에 접속후 운영체제에 맞는 설치파을을 다운로드 한다.

  2. 기존 설치자의 경우도 알아서 uninstall후 재설치가 자동으로 이뤄 진다.

출처

R Studio 공식 블로그


'AI > R Basic' 카테고리의 다른 글

두 개 데이터 프레임 병합, 빼기  (0) 2018.03.04
R Factor 검색  (0) 2017.11.13
rJava load 에러  (0) 2017.04.16
Swapping columns in a matrix  (0) 2017.03.31
R Notebook  (0) 2016.11.02

rJava load 에러



JDK를 업데이트 하면 발생한다.


JAVA_HOME 환경변수를 다시 설정해 준다.


cmd에서 확인 방법


echo %JAVA_HOME%


환경변수가 잘 변경 되었는지 위 방법을 통해서 알 수 있다. 

'AI > R Basic' 카테고리의 다른 글

R Factor 검색  (0) 2017.11.13
RStudio v1.1 Released  (0) 2017.10.10
Swapping columns in a matrix  (0) 2017.03.31
R Notebook  (0) 2016.11.02
R Markdown  (0) 2016.11.02

Swapping columns in a matrix


그냥 간단하게 column을 swapping한다면

m[, c(1,2)] <- m[,c(2,1)]

하지만 위에 처럼 하게 되면 column의 이름이 swap되지 않는다.

아래와 같이 수행해야 column 이름까지 모두 함께 변경 된다.

m <- m[, c(2, 1, 3:ncol(m))]


'AI > R Basic' 카테고리의 다른 글

RStudio v1.1 Released  (0) 2017.10.10
rJava load 에러  (0) 2017.04.16
R Notebook  (0) 2016.11.02
R Markdown  (0) 2016.11.02
Data를 그룹별로 요약 (Summarizing data)  (0) 2016.10.27

R Notebook


Python의 Jupyter Notebook과 다르게 R의 경우 그동안 R Markdown만 있을뿐 Interative한 Document 타입이 없어서 불편 했었다.

하지만 이번 R Studio preview 업데이트로 막강한 Notebook기능이 업데이트 되었다.

Data Analysis시 좀 더 체계적인 문서와 관리가 가능해진 것 같다.

RStudio v1.0.44 Preview — Release Notes

  • Authoring tools for R Notebooks.
  • Integrated support for the sparklyr package (R interface to Spark).
  • Enhanced data import tools based on the readr, readxl and haven packages.
  • Performance profiling via integration with the profvis package.
  • Authoring tools for R Markdown websites and the bookdown package.
  • Many other miscellaneous enhancements and bug fixes.

동작 모습

아래와 같이 Notebook생성 기능이 새로 만들어 졌다.

그리고 아래와 같이 preview버튼으로 실행하고 옵션을 in panel로 하면 viewer 창에 결과가 보이고
interactive 하게 편집할 수 있도록 바뀐다.


R Markdown


R Studio가 1.0이상의 버전이 되면서 많은 부분들이 개선 되었다.
그것들에 대해서 하나씩 이야기해본다.

기본 R Markdown

아래처럼 HTML을 생성 할 때 Option으로 toc: truetoc_float: true를 설정하면 왼쪽에 제목에 따른 목차가 생성 되는 것을 알 수 있다. 추가 html옵션을 보려면 ?html_document를 실행 한다.

title: "Viridis Demo 2"
output: 
  html_document:
    toc: true
    toc_float: true

패널에 preview 표시

preview in viewer panel을 선택하면 안에서 표시 할 수 있게 된다.


Data를 그룹별로 요약 (Summarizing data)


특정 값에 따라서 그룹으로 나눈다음 특정 함수(평균, SD)를 적용하는 방법은 3가지가 있다.

  • ddply해당 함수는 plyr package를 통해서 쉽게 사용할 수 있다.
  • summarizeBy() 해당 함수는 doBy package를 이용해서 쉽게 사용할 수 있다.
  • aggregate() 해당 함수는 약간 어렵지만, 기본 R 함수이다.

주어진 데이터 형태

data <- read.table(header=TRUE, text='
 subject sex condition before after change
       1   F   placebo   10.1   6.9   -3.2
       2   F   placebo    6.3   4.2   -2.1
       3   M   aspirin   12.4   6.3   -6.1
       4   F   placebo    8.1   6.1   -2.0
       5   M   aspirin   15.2   9.9   -5.3
       6   F   aspirin   10.9   7.0   -3.9
       7   F   aspirin   11.6   8.5   -3.1
       8   M   aspirin    9.5   3.0   -6.5
       9   F   placebo   11.5   9.0   -2.5
      10   M   placebo   11.9  11.0   -0.9
      11   F   aspirin   11.4   8.0   -3.4
      12   M   aspirin   10.0   4.4   -5.6
      13   M   aspirin   12.5   5.4   -7.1
      14   M   placebo   10.6  10.6    0.0
      15   M   aspirin    9.1   4.3   -4.8
      16   F   placebo   12.1  10.2   -1.9
      17   F   placebo   11.0   8.8   -2.2
      18   F   placebo   11.9  10.2   -1.7
      19   M   aspirin    9.1   3.6   -5.5
      20   M   placebo   13.5  12.4   -1.1
      21   M   aspirin   12.0   7.5   -4.5
      22   F   placebo    9.1   7.6   -1.5
      23   M   placebo    9.9   8.0   -1.9
      24   F   placebo    7.6   5.2   -2.4
      25   F   placebo   11.8   9.7   -2.1
      26   F   placebo   11.8  10.7   -1.1
      27   F   aspirin   10.1   7.9   -2.2
      28   M   aspirin   11.6   8.3   -3.3
      29   F   aspirin   11.3   6.8   -4.5
      30   F   placebo   10.3   8.3   -2.0
 ')

ddply 사용

library(plyr)

# Run the functions length, mean, and sd on the value of "change" for each group, 
# broken down by sex + condition
cdata <- ddply(data, c("sex", "condition"), summarise,
               N    = length(change),
               mean = mean(change),
               sd   = sd(change),
               se   = sd / sqrt(N)
)
cdata
#>   sex condition  N      mean        sd        se
#> 1   F   aspirin  5 -3.420000 0.8642916 0.3865230
#> 2   F   placebo 12 -2.058333 0.5247655 0.1514867
#> 3   M   aspirin  9 -5.411111 1.1307569 0.3769190
#> 4   M   placebo  4 -0.975000 0.7804913 0.3902456

참고자료

http://www.cookbook-r.com/Manipulating_data/Summarizing_data/


'AI > R Basic' 카테고리의 다른 글

R Notebook  (0) 2016.11.02
R Markdown  (0) 2016.11.02
리스트 데이터 프레임을 단일 큰 데이터 프레임으로 변환, identical  (0) 2016.10.10
Word Cloud from PDF using R  (1) 2016.08.25
빈도분석 표와 백분율 구하기  (0) 2016.08.21

리스트 데이터 프레임을 단일 큰 데이터 프레임으로 변환


do.call 방식

id가 따로 생성되지 않아서 나중에 식별이 어렵다.

df <- do.call("rbind", listOfDataFrames)

plyr pakcage의 ldply이용

.id로 index를 만들기 때문에 여러므로 편리하다.
ldply을 사용하는것이 좋다.
plyr package를 반드시 부착 한다.

df <- ldply(listOfDataFrames, data.frame)
system.time({ df <- do.call("rbind", listOfDataFrames) })
user  system elapsed 
0.25    0.00    0.25 


ldply(phoneStatusDf, function(x){
  x[,2]  
})
system.time({ df2 <- ldply(listOfDataFrames, data.frame) })
user  system elapsed 
0.30    0.00    0.29
identical(df, df2)
[1] TRUE

빠른 속도: rbindlist

library("data.table")
rbindlist(listOfDataFrames, idcol=TRUE)

idcol의 옵션에 따라서 .id 컬럼이 생성된다.


'AI > R Basic' 카테고리의 다른 글

R Markdown  (0) 2016.11.02
Data를 그룹별로 요약 (Summarizing data)  (0) 2016.10.27
Word Cloud from PDF using R  (1) 2016.08.25
빈도분석 표와 백분율 구하기  (0) 2016.08.21
Vector 분할  (0) 2016.08.21

이 때 까지 출판한 논문들을 이용해서 Word Cloud를 생성해 보았다.

저전력 컴퓨팅을 주로 했지만 어느 순간 부터 모델링을 하다보니 기계학습 내용도 많이 공부하게 됬다.

스스로의 학문적 근간이 모호해지는 상황이다.

최종적으로 생성한 Word Cloud는 아래와 같다.


해당 코드는 아래의 필자의 Github에 업로드 했다.

https://github.com/leejaymin/WordCloud 


Word Cloud from PDF using R


This project is to create Wrold Cloud from PDF file.
My code shows how a word cloud can be generated using the Rprogramming language on the basis of a given PDF document.

Used packages are as bellow:

  • tm (text mining)
  • wordcloud
  • RColorBrewer (fancy colors in a word cloud)

Code strcture

  • Loading the required libraries and setting inital parameters
  • Reading the text in the PDF file
  • Creating the text corpus
  • Generating the word cloud. This result is the following:

  • Anlyzing word frequency is as follow.

Reference

[1] Using R to create a Wrod Cloud from a PDF Document
[2] Basic Text mining in R


빈도분석 표와 백분율 구하기


descr package

질적 자료의 빈도와 백분율을 구하고 싶을 때, 유용한 함수로는 descr 패키지에 있는 freq()가 있다.

# 사용법 : freq(질적 자료)
# 예제 데이터 : InsectSprays
> attach(InsectSprays)

>install.packages("descr")
>library(descr)...

# 빈도표 작성하기 : 빈도와 백분율을 한번에 구해 준다.
> freq(spray)

# 빈도표와 막대그래프 작성하기
> freq(spray, plot=TRUE)

plyr package

install.packages('plyr')

Then, call its library, and the count() function will be ready for use.
> library(plyr)
> count(mtcars, 'gear')
       gear      freq
1      3         15
2      4         12
3      5         5
> y = count(mtcars, 'gear')
> y
       gear      freq
1      3         15
2      4         12
3      5         5
> class(y)
[1] "data.frame"

정렬하기

plyr페키지의 arrange를 사용

> library(plyr)

> arrange(v123, v1, desc(v2), v3)

  v1   v2 v3

1 30 6500  B

2 40 5100  A

3 40 4500  A

4 50 3000  B

5 50 2000  A

6 50 2000  B

7 90 9000  A 


Vector 분할


한줄로 해결 가능하다.

split(d, ceiling(seq_along(d)/20))

seq_along()split()ceiling()을 좀 더 자세히 설명하면 아래와 같다.

> d <- rpois(73,5)
> d
 [1]  3  1 11  4  1  2  3  2  4 10 10  2  7  4  6  6  2  1  1  2  3  8  3 10  7  4
[27]  3  4  4  1  1  7  2  4  6  0  5  7  4  6  8  4  7 12  4  6  8  4  2  7  6  5
[53]  4  5  4  5  5  8  7  7  7  6  2  4  3  3  8 11  6  6  1  8  4
> max <- 20
> x <- seq_along(d)
> d1 <- split(d, ceiling(x/max))
> d1
$`1`
 [1]  3  1 11  4  1  2  3  2  4 10 10  2  7  4  6  6  2  1  1  2

$`2`
 [1]  3  8  3 10  7  4  3  4  4  1  1  7  2  4  6  0  5  7  4  6

$`3`
 [1]  8  4  7 12  4  6  8  4  2  7  6  5  4  5  4  5  5  8  7  7

$`4`
 [1]  7  6  2  4  3  3  8 11  6  6  1  8  4


테스트 주도의 개발을 위한 Unit Test in R


유닛 테스트를 통한 Test Driven Development (TDD)를 생각해 보자.

RUnit 테스팅을 위해서는 RUnit와 testthat 두 개의 package가 존재 한다.

사용할 수 있는 함수

  • expect_true(x): x가 참인가

  • expect_false(x): x가 거짓인가

  • expect_equal(object, expected): object가 기대되는 값 expected와 동일한가. 값의 비교에는 all.equal()이 사용되며 all.equal()은 두 객체가 (거의) 같은지를 비교한다. 따라서 부동소수의 경우 epsilon 이하로 차이나는 두 값은 같은 값으로 취급한다.

  • expect_equivalent(x,y): x,y가 동등한가. expect_equal()과 달리 속성 (예를 들면, rownames)을 제거한 뒤 값만 비교 한다.

생성한 파일 구조는 아래와 같다.

tests/test_fibo.R #test case가 저장됨
run_tests.R #test 실행 명령어들의 집함
fibo.R # test할 함수가 저장됨

소스코드

fibo.R

fibo <- function(n){
  if(n==0 || n == 1){
    return(1)
  }
  return(fibo(n-1) + fibo(n-2))
}

run_tests.R

require(testthat)
source("fibo.R")

test_dir("tests", reporter="summary")

tests/test_fibo.R

context("fibonacci series")

test_that("base test",{
  expect_equal(1, fibo(0))
  expect_equal(1, fibo(1))
})

test_that("recursion test",{
  expect_equal(2, fibo(2))
  expect_equal(3, fibo(3))
  expect_equal(5, fibo(4))
})

실행 결과

정상적인경우

> source("run_tests.R")
fibonacci series: .....

DONE ============================================================================================================================================

의도적으로 오류를 발생 시키자

  expect_equal(0, fibo(4))

문제가 있는 경우

> source("run_tests.R")
fibonacci series: ....1

Failed ------------------------------------------------------------------------------------------------------------------------------------------
1. Failure: recursion test (@test_fibo.R#12) ----------------------------------------------------------------------------------------------------
0 not equal to fibo(4).
1/1 mismatches
[1] 0 - 5 == -5


DONE ============================================================================================================================================

참고문헌

[1] R을 이용한 데이터 처리 & 분석 실무, 서민구


Missing Value

How do I replace NA values with zeros in R

> m <- matrix(sample(c(NA, 1:10), 100, replace = TRUE), 10)
> d <- as.data.frame(m)
   V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
1   4  3 NA  3  7  6  6 10  6   5
2   9  8  9  5 10 NA  2  1  7   2
3   1  1  6  3  6 NA  1  4  1   6
4  NA  4 NA  7 10  2 NA  4  1   8
5   1  2  4 NA  2  6  2  6  7   4
6  NA  3 NA NA 10  2  1 10  8   4
7   4  4  9 10  9  8  9  4 10  NA
8   5  8  3  2  1  4  5  9  4   7
9   3  9 10  1  9  9 10  5  3   3
10  4  2  2  5 NA  9  7  2  5   5

> d[is.na(d)] <- 0

> d
   V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
1   4  3  0  3  7  6  6 10  6   5
2   9  8  9  5 10  0  2  1  7   2
3   1  1  6  3  6  0  1  4  1   6
4   0  4  0  7 10  2  0  4  1   8
5   1  2  4  0  2  6  2  6  7   4
6   0  3  0  0 10  2  1 10  8   4
7   4  4  9 10  9  8  9  4 10   0
8   5  8  3  2  1  4  5  9  4   7
9   3  9 10  1  9  9 10  5  3   3
10  4  2  2  5  0  9  7  2  5   5

listwise deletion of missing values

# create new dataset without missing data 
newdata <- na.omit(mydata)

na.locf 함수 사용

zoo package에 구현되어 있는 함수이다.

Last Observation Carried Forward

Generic function for replacing each NA with the most recent non-NA prior to it.

x <- c(NA,NA, "A","A", "B","B","B", NA,NA, "C", NA,NA,NA, "A","A","B", NA,NA)
na.locf(x)
x

출력 결과

 [1] "A" "A" "B" "B" "B" "B" "B" "C" "C" "C" "C" "A" "A" "B" "B" "B"

참고 사이트: http://www.cookbook-r.com/Manipulating_data/Filling_in_NAs_with_last_non-NA_value/


병렬화를 통한 연산 성능 향상


성능 측정 방법: system.time과 R profiler

특정함수에 대한 시간만 보고싶으면 간단하게 system.time함수를 이용한다.

아래와 같이 do.call ldply의 성능을 비교한 것이다.
user, sys, elapsed이 세가지 관점으로 시간을 나타내주게 된다.

> ptList <- list(1:100000)
> system.time(do.call(rbind,ptList))
 사용자  시스템 elapsed 
      0       0       0 
> system.time(ldply(ptList,rbind))
 사용자  시스템 elapsed 
   0.17    0.00    0.17

사용자(user): 시간의 경우 프로그램 코드 자체를 R에서 수행한 시간이다.

시스템(sys): 시간의 경우 운영체제(OS)가 대신 작업을 처리하는데 걸린 시간이다. 예를 들면 save()또는 load()함수의 경우 sys 시간이 더 길게 된다. 이는 OS 작업을 통해서 파일 입출력을 수행하기 때문이다.
sys 시간이 크다면 메모리 부족도 의심해 봐야한다. R은 기본적으로 메모리에 모든 오브젝트를 로드하고 처리하므로 만약 메모리가 부족할경우 페이지 폴트가 지속적으로 발생해서 성능저하의 원인이 된다.

경과(elapsed): 시간는 가장 이해하기 쉬운 개념으로 프로그램 시작할 때 시간을 측정해서 끝날 때 종료한 시간 차이이다.

병렬 프로세싱 (doParallel, Window도 가능)

doMC는 내부적으로 fork()를 이용하기 때문에 linux에서 동작 하게 된다.
doParallel는 윈도우에서 사용 할 수 있는 package를 의미한다.

상세 관련 문서 vignette(“gettingstartedParallel”)

doParallel은 내부적으로 multicore, foreach, snow를 사용하기 때문에snow의 기능인 다수의 머신에 클러스터를 구현하는 기능을 제공하므로 doMC보다 더 막강하다고 할 수 있다.

install.packages("doParallel")
library(doParallel)

프로세스의 수 설정

코어의 수를 설정 한다.

registerDoParallel(cores=4)

작업관리자를 보면, Rscript.exe가 존재 하는 것을 알 수 있다.

plyr의 병렬화

{adl}{adl_}ply

형태의 함수들의 도움말을 살펴보면 .parallel 옵션이 있다. 이 옵션 값이 TRUE로 설정 되면
registerDoParallel()을 사용해 설정한 만큼의 프로세스가 동시에 실행되어 데이터를 병렬적으로 처리한다.

foreach의 병렬화

이미 for보다는 apply 계열의 함수가 더 빠르다는 것을 알고 있다.
foreach는 이러한 apply보다 더 빠른 loop연산 함수 이다.
그 이유가 바로 간단한 병렬화를 지원하기 때문이다.

foreach()는 기본적으로 %do를 사용해 실행할 명령의 블록을 지정해야 한다.
만약 foreach()에서 블록 내 명령을 병렬로 수행하고자 한다면registerDoParallel()을 한 뒤 foreach() %do% 대신 %dopar%를 지정하면 된다.

registerDoParallel로 core 수를 결정하면 실행 중인 프로세스 목록에 Rscript.exe라는 프로세스들이 설정한 코어 갯수 만큼 생성된것을 알 수 있다. 반복적으로registerDoParallel을 실행하면 해당 프로세스가 계속해서 늘어나기 때문에 이를 막기 위해서 명시적으로 stopImplicitCluster()를 해주는 것이 좋다.R-session을 종료하면 자동으로 정리해 주긴 하지만 말이다.

foreach는 apply()계열의 함수와 for()를 대체할 수 있는 루프문을 위한 함수 이다.
for문과의 가장 큰 차이는 반환 값이 있다는 점이다. 또한 {}가 아닌 %do%문을 사용해 블록을 지정한다는 점이다.

foreach::foreach(
    ... # 표현식 ex에 넘겨줄 인자
    # .combine은 ex에서의 반환 값을 어떻게 합칠지 지정한다. cbind(컬럼 방향으로 합친 데이터 프레임 반환),
    # rbind(행 방향으로 합친 데이터 프레임 반환), c(벡터로 반환) 등이 그예다. 기본값은 결과를 리스트로 합친다.
    .combine
    %do% ex # ex는 평가할 표현식
)

단순히 foreach만 사용할 경우

system.time(l1 <- rnorm(10000000))

library(foreach)
system.time(l2 <- foreach(i=1:4, .combine = 'c')
            %do% rnorm(2500000))

> system.time(l1 <- rnorm(10000000))
 사용자  시스템 elapsed 
   0.75    0.00    0.75 
> 
> library(foreach)
> system.time(l2 <- foreach(i=1:4, .combine = 'c')
+             %do% rnorm(2500000))
 사용자  시스템 elapsed 
   0.78    0.00    0.78

오히려 속도가 느려지는 것을 알 수 있다.

doParallel과 같이 이용
좀더 차이를 주기위해서 이전 예제보다 10대 갯수를 증가 시켰다.

> system.time(l1 <- rnorm(100000000))
 사용자  시스템 elapsed 
   7.38    0.14    7.55 
> 
> library(foreach)
> system.time(l2 <- foreach(i=1:4, .combine = 'c')
+             %do% rnorm(25000000))
 사용자  시스템 elapsed 
   8.28    0.28    8.58 

> library(doParallel)
> registerDoParallel(cores = 8)
> system.time(l3p <- foreach(i=1:10, .combine = 'c')
+             %dopar% rnorm(10000000))
 사용자  시스템 elapsed 
   1.54    2.25    5.15 
> stopImplicitCluster()

> length(l1)
[1] 100000000
> length(l2)
[1] 100000000
> length(l3p)
[1] 100000000

코어를 8개로 병렬화 했지만 8배까지는 아니고 2배정도 향상된것 같다.
데이터 분할 및 병합 overhead 때문에 발생하는 통상의 문제이다.
또한 i7-processor 특징상 물리적으로는 4-cores 지만 HT기술을 고려해서 논리적으론 8개로 잡았다.

작업이 끝나면 stopImplicitCluster()를 실행해서 closing doParallel cluster를 수행 시켜 주자.

하지만, stopImplicitCluster()을 수행할경우 apply()계열의 함수들이 connection error가 발생 하므로
모든 작업이 끝난 다음에 한번만 호출해 주자.

foreach 기타 옵션들

foreach값이 return하는 list/data.frame에 이름을 부여하고 싶을 경우
.final = function(x) setName(x, names(foo))를 이용한다.
.final은 마지막에 한번만 호출되게 된다.

foo <- list(a = 1, b = 2)
bar <- foreach (x = foo, .final = function(x) setNames(x, names(foo))) %do% {
    x * 2
    }

병렬 프로세싱 (Parallel package, Linux 전용)

set up worker processes that can complete tasks simultaneously.

It does this by including components of the multicore and snow packages, each taking a different approach towards multitasking.

To determine the number of cores your machine has, use the detectCores()function as follows.

An easy way to get started with the multicore functionality is to use themclappy() function, which is a parallel version of lapply().

mclapply {parallel}

mclapply(X, FUN, ..., mc.preschedule = TRUE, mc.set.seed = TRUE,
         mc.silent = FALSE, mc.cores = 1L,
         mc.cleanup = TRUE, mc.allow.recursive = TRUE)

참고자료

http://www.exegetic.biz/blog/2013/08/the-wonders-of-foreach/


위도,경도를 주소로 변환 ggmap package를 이용한 (geocoding and revgeocode in R)


GGMAP package

geocode

geocode함수는 latitude와 longitude를 가지고 location으로 변환 하는것을 말한다.
이것은 Google Map을 이용하게 된다.

Usage

geocode(location, output = c("latlon", "latlona", "more", "all"),
source = c("google", "dsk"), messaging = FALSE, force = ifelse(source ==
"dsk", FALSE, TRUE), sensor = FALSE, override_limit = FALSE,
client = "", signature = "", nameType = c("long", "short"), data)
geocodeQueryCheck(userType = "free")

예제

library(ggmap)

gc <- as.numeric(geocode('Baylor University'))
revgeocode(gc, output = 'more')
revgeocode(gc, output = 'all')

as.numeric(dfLocation[3,])
revgeocode(as.numeric(dfLocation[2:3,]),output = 'more')
revgeocode(latlng,output = 'more')
revgeocode(latlng, ics = 'WGS-84', api = 'google', output = 'address')

data.frame에 기록된 longitude와 latitude를 이용해서 Place로 변환하는 코드이다.

place <- adply(dfLocation, 1,function(x){
    revgeocode(as.numeric(x),output = 'more')
    }
)

test code

Using Google Maps API and R

library(RCurl)
library(RJSONIO)
library(plyr)

url <- function(address, return.call = "json", sensor = "false") {
    root <- "http://maps.google.com/maps/api/geocode/"
    u <- paste(root, return.call, "?address=", address, "&sensor=", sensor, sep = "")
    return(URLencode(u))
}

geoCode <- function(address,verbose=FALSE) {
    if(verbose) cat(address,"\n")
    u <- url(address)
    doc <- getURL(u)
    x <- fromJSON(doc,simplify = FALSE)
    if(x$status=="OK") {
        lat <- x$results[[1]]$geometry$location$lat
        lng <- x$results[[1]]$geometry$location$lng
        location_type  <- x$results[[1]]$geometry$location_type
        formatted_address  <- x$results[[1]]$formatted_address
        return(c(lat, lng, location_type, formatted_address))
        Sys.sleep(0.5)
    } else {
        return(c(NA,NA,NA, NA))
    }
}
address <- geoCode("The White House, Washington, DC")


'AI > R Basic' 카테고리의 다른 글

Missing Value  (0) 2016.03.20
병렬화를 통한 연산 성능 향상 및 성능 측정 방법  (0) 2016.03.06
Do.call()  (0) 2016.02.05
날짜 시간 변환 (Date-Time Conversion Function in R)  (0) 2015.12.14
JSON in R using jsonlite  (0) 2015.12.12

Do.call()


데이터는 리스트 구조에 담겨져 있다.
이 데이터를 어떤 함수로 전달하고 싶지만 그 함수는 리스트를 인자로 받을 수 없는 구조이다.

해결책
1. 리스트를 벡터로 변환한다.
2. do.call함수로 리스트를 개별 인자들로 분해한 쓰려고 하는 함수에 적용 한다.

do.call(function, list)

예제 아래와 같이 중첩 리스트(nested list)일 경우에 데이터행렬로 변경하기가 골치아프게 된다.

> list <- list(col1 = list (1,2,3), col2 = list(3,4,5), col3 = list(6,7,8))
> list
$col1
$col1[[1]]
[1] 1

$col1[[2]]
[1] 2

$col1[[3]]
[1] 3


$col2
$col2[[1]]
[1] 3

$col2[[2]]
[1] 4

$col2[[3]]
[1] 5


$col3
$col3[[1]]
[1] 6

$col3[[2]]
[1] 7

$col3[[3]]
[1] 8

# cbind를 수행해도 원하는 않는 코드가 생성 된다.
> cbind(list)
     list  
col1 List,3
col2 List,3
col3 List,3


# data.frame()을 수행해도 이상한 결과이다.
> as.data.frame(list)
  col1.1 col1.2 col1.3 col2.3 col2.4 col2.5 col3.6 col3.7 col3.8
1      1      2      3      3      4      5      6      7      8

> unlist(list)
col11 col12 col13 col21 col22 col23 col31 col32 col33 
    1     2     3     3     4     5     6     7     8 

> cbind(unlist(list))
      [,1]
col11    1
col12    2
col13    3
col21    3
col22    4
col23    5
col31    6
col32    7
col33    8

#비로써 적절히 행과 열이 나뉘어서 합쳐지는 것을 볼 수 있다.
> do.call(cbind,list)
     col1 col2 col3
[1,] 1    3    6   
[2,] 2    4    7   
[3,] 3    5    8 


Date-Time Conversion Function in R


R에서는 이것의 처리를 위해서 POSIXlt POSICct를 사용 할 수 있다.

예제

> Sys.time()
[1] "2015-12-12 13:08:11 KST"
w
> Sys.timezone()
[1] "Asia/Seoul"

> Sys.Date()
[1] "2015-12-12"