반응형
Subsetting
Subsetting 의 6가지 종류
x <- c(2.1, 4.2, 3.3, 5.4)
# 1.positive integer
x[c(3, 1)]
#> [1] 3.3 2.1
# 2. negative integer
x[-c(3, 1)]
#> [1] 4.2 5.4
# 3. Logical vector
x[c(TRUE, TRUE, FALSE, FALSE)] # logical vector 는 그 position 의 값이 TRUE 인 것만 반환한다.
#> [1] 2.1 4.2
x[c(TRUE, FALSE)] # 길이가 짧을 경우 반복해서 적용된다.
#> [1] 2.1 3.3
x[x > 3]
#> [1] 4.2 3.3 5.4
# 4. nothing. 원래 값을 반환
x[]
#> [1] 2.1 4.2 3.3 5.4
# 5. 0. zero-length vector를 반환한다.
x[0]
#> numeric(0)
# 6. character vector (name 이 있는 경우)
(y <- setNames(x, letters[1:4]))
#> a b c d
#> 2.1 4.2 3.3 5.4
y[c("d", "c", "a")]
#> d c a
#> 5.4 3.3 2.1
z <- c(abc = 1, def = 2)
z[c("a", "d")]
#> <NA> <NA>
#> NA NA
List
a <- list(a = c(1,2,3), b = c("a", "b"),
c = array(c(1,2,3), c(1,3)))
a
#> $a
#> [1] 1 2 3
#>
#> $b
#> [1] "a" "b"
#>
#> $c
#> [,1] [,2] [,3]
#> [1,] 1 2 3
a$a
#> [1] 1 2 3
a[1] # []는 항상 list 를 반환한다.
#> $a
#> [1] 1 2 3
a[[1]] # 해당 위치의 element 를 반환한다.
#> [1] 1 2 3
Matrices and array
a <- matrix(1:9, nrow = 3)
colnames(a) <- c("A", "B", "C")
a
#> A B C
#> [1,] 1 4 7
#> [2,] 2 5 8
#> [3,] 3 6 9
# integer vector를 통한 subsetting
a[1:2, ]
#> A B C
#> [1,] 1 4 7
#> [2,] 2 5 8
# logical vector와 character vector (name attribute 가 있을 때) 를 통한 subsetting
a[c(TRUE, FALSE, TRUE), c("B", "A")]
#> B A
#> [1,] 4 1
#> [2,] 6 3
# 한 개의 vector를 통한 subsetting
(vals <- outer(1:5, 1:5, FUN = "paste", sep = ","))
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] "1,1" "1,2" "1,3" "1,4" "1,5"
#> [2,] "2,1" "2,2" "2,3" "2,4" "2,5"
#> [3,] "3,1" "3,2" "3,3" "3,4" "3,5"
#> [4,] "4,1" "4,2" "4,3" "4,4" "4,5"
#> [5,] "5,1" "5,2" "5,3" "5,4" "5,5"
# 중간에 , 가 없는 경우 R 은 column 우선
vals[c(4, 15)]
#> [1] "4,1" "5,3"
# matrix 또는 array 를 통한 subsetting
vals <- outer(1:5, 1:5, FUN = "paste", sep = ",")
select <- matrix(ncol = 2, byrow = TRUE, c(
1, 1,
3, 1,
2, 4
))
vals[select]
#> [1] "1,1" "3,1" "2,4"
# 위 방법은 이 결과와 같음
c(vals[1, 1], vals[3, 1], vals[2, 4])
#> [1] "1,1" "3,1" "2,4"
Data frame
df <- data.frame(x = 1:3, y = 3:1, z = letters[1:3])
# Raw subsetting
df[df$x == 2, ]
#> x y z
#> 2 2 2 b
df[c(1, 3), ]
#> x y z
#> 1 1 3 a
#> 3 3 1 c
# Column subsetting
# Data frame은 matrix 와 list 의 성질을 동시에 갖는다.
df[c("x", "z")] # list 처럼 다루는 방법
#> x z
#> 1 1 a
#> 2 2 b
#> 3 3 c
df[, c("x", "z")] # matrix 처럼 다루는 방법
#> x z
#> 1 1 a
#> 2 2 b
#> 3 3 c
str(df["x"]) # list 로 subset 된다.
#> 'data.frame': 3 obs. of 1 variable:
#> $ x: int 1 2 3
str(df[, "x"]) # vector 로 subset 된다.
#> int [1:3] 1 2 3
S3 Object
- S3 object 는 atomic vector, list, array 위에서 만들어짐. 따라서 위의 방법들을 활용할 수 있음.
- str 을 사용해 S3 object 의 구조를 파악하고 위 방법들을 똑같이 활용할 수 있음
Excercise : S3 Object subsetting
- lm fitting 후 r square 추출하기
library(pryr)
mod <- lm(mpg ~ wt, data = mtcars)
summ <- summary(mod)
attributes(summ)
#> $names
#> [1] "call" "terms" "residuals" "coefficients"
#> [5] "aliased" "sigma" "df" "r.squared"
#> [9] "adj.r.squared" "fstatistic" "cov.unscaled"
#>
#> $class
#> [1] "summary.lm"
summ$r.squared
#> [1] 0.7528328
Simplifying vs. Preserving subsetting
- Simplifying : subsetting 시 output을 최대한 간단하게 표현하는 것
- Preserving : subsetting 시 output 을 input 과 같게 유지하는 것
Vector
x <- c(a = 1, b = 2)
x[1] # preserving
#> a
#> 1
x[[1]] # simplifying. name attribute 를 버린다.
#> [1] 1
List
y <- list(a = 1, b = 2)
y[1] # preserving
#> $a
#> [1] 1
y[[1]] # simplifying
#> [1] 1
y$a # simplifying
#> [1] 1
Factor
z <- factor(c("a", "b"))
z[1] # preserving
#> [1] a
#> Levels: a b
z[1, drop = TRUE] # simplifying
#> [1] a
#> Levels: a
Matrix
a <- matrix(1:4, nrow = 2)
a[1, , drop = FALSE] # preserving
#> [,1] [,2]
#> [1,] 1 3
a[1, ] # simplifying
#> [1] 1 3
Data frame
df <- data.frame(a = 1:2, b = 1:2)
df[1] # preserving
#> a
#> 1 1
#> 2 2
df[[1]] # simplifying
#> [1] 1 2
df[, "a", drop = FALSE] # preserving
#> a
#> 1 1
#> 2 2
df[, "a"] # simplifying
#> [1] 1 2
df$a
#> [1] 1 2
$와 [[]] 의 차이
var <- "cyl"
mtcars$var
#> NULL
[[]] 는 column 명을 변수로 줄 수 있음
# Instead use [[
mtcars[[var]]
#> [1] 6 6 4 6 8 6 8 4 4 6 6 8 8 8 8 8 8 4 4 4 4 8 8 8 8 4 4 4 8 6 8 4
$ 는 partial matching 을 사용함 [[]] 는 안됨
x <- list(abc = 1)
x$a # $ does partial matching
#> [1] 1
Subsetting and assignment
- R 에서는 subset 하는 것처럼 값을 할당할 수 있음
x <- 1:5
x[c(1, 2)] <- 2:3
x
#> [1] 2 3 3 4 5
Excercise
Boostrap + Random feature selection 구현하기 - 전체 샘플의 50 % 크기를 중복을 허용해 추출하고, 열의 70 % 를 임의로 골라 Subsetting 해보기. (ID, Class 열 제외)
library(mlbench)
data("BreastCancer")
head(BreastCancer)
#> Id Cl.thickness Cell.size Cell.shape Marg.adhesion Epith.c.size
#> 1 1000025 5 1 1 1 2
#> 2 1002945 5 4 4 5 7
#> 3 1015425 3 1 1 1 2
#> 4 1016277 6 8 8 1 3
#> 5 1017023 4 1 1 3 2
#> 6 1017122 8 10 10 8 7
#> Bare.nuclei Bl.cromatin Normal.nucleoli Mitoses Class
#> 1 1 3 1 1 benign
#> 2 10 3 2 1 benign
#> 3 2 3 1 1 benign
#> 4 4 3 7 1 benign
#> 5 1 3 1 1 benign
#> 6 10 9 7 1 malignant
num_row <- nrow(BreastCancer)
num_col <- length(BreastCancer)
raws_to_keep <- sample(num_row, 0.5 * num_row, replace = TRUE) # integer vector 를 통한 subsetting
cols_names <- colnames(BreastCancer)
features <- cols_names[!(cols_names %in% c('Id', "Class"))] # logical vector를 통한 subsetting
cols_to_keep <- c('Id', "Class", sample(features, 0.7 * num_col)) # character vector 를 통한 subsetting
BreastCancerSample <- BreastCancer[raws_to_keep, cols_to_keep]
head(BreastCancerSample)
#> Id Class Mitoses Cell.size Normal.nucleoli Cell.shape
#> 513 1299994 benign 1 1 1 1
#> 374 521441 benign 1 1 1 1
#> 433 1277629 benign 1 1 2 1
#> 444 734111 benign 1 1 1 1
#> 649 1315807 malignant 10 10 10 10
#> 180 1202812 malignant 1 3 1 3
#> Cl.thickness Epith.c.size Bl.cromatin
#> 513 5 2 1
#> 374 5 2 2
#> 433 5 2 2
#> 444 1 2 1
#> 649 5 10 10
#> 180 5 6 3
반응형
'Tools > R' 카테고리의 다른 글
R Studio 간단한 팁과 트릭 (1) | 2019.04.28 |
---|---|
R 중급 - 함수의 기초 (Functions) (0) | 2019.04.09 |
R 중급 - 데이터 구조 심화 (Data structure) (0) | 2019.04.09 |
해들리 위컴은 어떻게 수많은 R 패키지를 개발할 수 있었을까? (0) | 2019.04.07 |
R 중급 - apply 계열 함수 정리 (apply, lapply, sapply, tapply, mapply) (7) | 2019.04.01 |