R은 데이터의 저장과 조작을 위한 정교한 구조를 제공한다.
이러한 구조는 데이터 표현, 조작 및 분석을 단순화한다.
Factor는 미리 정의된 값만을 포함할 수 있는 벡터로, 범주형 데이터를 저장하는 데 사용된다.
Factor는 두 가지 속성을 사용하는 정수 벡터 위에 구축된다:
class “factor”는 이를 일반 정수 벡터와 다르게 동작하게
만들며, levels는 허용된 값의 집합을 정의한다.
factor를
적용한다.hair <- c("blonde", "black", "brown", "brown", "black", "gray", "none")
is.character(hair)
## [1] TRUE
is.factor(hair)
## [1] FALSE
위에서 hair는 factor는 아니며, character 벡터이다.
이것을 factor로 바꿔보자.
hair <- factor(hair)
is.factor(hair)
## [1] TRUE
class(hair)
## [1] "factor"
levels(hair)
## [1] "black" "blonde" "brown" "gray" "none"
table() 함수는 팩터의 각 수준(level)이 나타나는 횟수를
계산한다.
table(hair)
## hair
## black blonde brown gray none
## 2 1 2 1 1
levels 인수를 사용하여 수준(level)을 지정한다.
hair <- factor(hair, levels=c("black", "blonde", "brown", "gray", "white", "none"))
table(hair)
## hair
## black blonde brown gray white none
## 2 1 2 1 0 1
수준(level)에 없는 값을 사용할 수 없다.
hair[2] <- "green"
## Warning in `[<-.factor`(`*tmp*`, 2, value = "green"): invalid factor level, NA
## generated
hair
## [1] blonde <NA> brown brown black gray none
## Levels: black blonde brown gray white none
# reset
hair[2] <- "black"
사실, factor의 타입은 정수이다.
typeof(hair)
## [1] "integer"
각 레벨을 정수화하여 표현해 볼 수 있다.
as.numeric(hair)
## [1] 2 1 3 3 1 4 6
Dataframe은 R에서 데이터를 저장하는 가장 일반적인 방법이다.
data.frame()을 사용하여 데이터프레임을 생성하며, 이
함수는 이름이 지정된 벡터들이나 기존의 데이터프레임을 입력으로
받는다:
data.frame(col1=x1, col2=x2, ..., df1, df2, ...)
col1과 col2는 열 이름이다.
x1과 x2는 길이가 같은
벡터들이다.
df1과 df2는 데이터프레임이며, 이들의
열은 x1, x2와 같은 길이여야 한다.
df <- data.frame(x = 2:4, y = c("a", "b", "c"))
str(df) #결과는 3개의 행과 2개의 열이 있음.
## 'data.frame': 3 obs. of 2 variables:
## $ x: int 2 3 4
## $ y: chr "a" "b" "c"
print(df)
## x y
## 1 2 a
## 2 3 b
## 3 4 c
data.frame()은 R 3.x 및 2.x에서 문자열을 팩터로
변환한다.
이 동작을 억제하려면 stringsAsFactors = FALSE를
사용하라:
(R 4.x에서는 stringsAsFactors = FALSE가 기본값으로
설정되어 있다.)
df <- data.frame(
x = 2:4,
y = c("a", "b", "c"),
stringsAsFactors = FALSE)
# R에서 객체의 구조를 간략하게 보여준다.
str(df)
## 'data.frame': 3 obs. of 2 variables:
## $ x: int 2 3 4
## $ y: chr "a" "b" "c"
df <- data.frame(
x = 2:4,
y = c("a", "b", "c"),
stringsAsFactors = TRUE) #factor로 바꾸고 싶으면 TRUE로
str(df)
## 'data.frame': 3 obs. of 2 variables:
## $ x: int 2 3 4
## $ y: Factor w/ 3 levels "a","b","c": 1 2 3
typeof(df)
## [1] "list"
class(df)
## [1] "data.frame"
is.data.frame(df)
## [1] TRUE
typeof(df): 이 함수는 객체 df의 내부
저장 모드를 반환한다. 데이터프레임의 경우, 보통 "list"를
반환한다. 이는 데이터프레임이 내부적으로 벡터들의 리스트라는 것을
의미한다.
class(df): 이 함수는 객체 df의 클래스
속성을 반환한다. 데이터프레임의 경우, "data.frame"을
반환하여 객체가 R에서 데이터프레임으로 인식되고 있음을
나타낸다.
is.data.frame(df): 이 함수는 객체 df가
데이터프레임인지 확인한다. df가 데이터프레임이면
TRUE를 반환하고, 그렇지 않으면 FALSE를
반환한다.
Dataframe들을 합치기:
cbind(df, data.frame(z = 3:1))
## x y z
## 1 2 a 3
## 2 3 b 2
## 3 4 c 1
rbind(df, data.frame(x = 10, y = "z"))
## x y
## 1 2 a
## 2 3 b
## 3 4 c
## 4 10 z
파일로부터 데이터프레임을 생성하기 위해 read.table을
사용할 수 있다.
다음의 가상의 데이터를 고려해 보자.
| Plot | Tree | Species | Diameter | Height |
|---|---|---|---|---|
| 2 | 1 | DF | 39 | 20.5 |
| 2 | 2 | WL | 48 | 33.0 |
| 3 | 2 | GF | 52 | 30.0 |
| … | … | … | … | … |
대형 데이터프레임은 보통 파일로부터 read.table을
사용하여 R로 읽어들인다.
read.table(file, header=FALSE, sep="")
file
header
sep
""는 특수 해석으로, 가변적인 양의 공백(공백,
탭, 줄바꿈)이 값을 구분할 수 있음을 의미한다.read.table의 두 가지 일반적으로 사용되는 변형
read.csv(file)
read.table(file, header=TRUE, sep=",")와 동등하다read.delim(file)
read.table(file, header=TRUE, sep="\t")와 동등하다names 함수를 사용하여 자신의
열 이름을 지정할 수 있다.col.names 인수를 사용하여 데이터프레임을 읽을 때
직접 지정할 수 있다.
col.names 인수도 없는 경우, R은 “V1”, “V2”
등의 이름을 사용한다.ufc.csv는 쉼표로 구분되어 있으며, 헤더 라인이
존재한다.
"the path of ufc.csv"에
ufc.csv 파일의 위치를 지정한다.ufc <- read.csv("the path of ufc.csv")
예를 들어, ufc.csv 파일이 현재 작업 디렉토리 아래의
/data/에 존재한다면 다음과 같이 작성한다.
아래에서 .는 현재 작업 디렉토리를 의미한다.
현재 작업 디렉토리는 getwd()를 code chunk 안에서
실행하여 확인할 수 있다.
ufc <- read.csv("./data/ufc.csv") # .을 현재 디렉토리를 의미(SSUR)
# ..은 한 단계 위를 의미
#현재 작업 디렉토리를 확인
getwd()
내용을 살펴보기 위해 head와 tail 함수를
사용해 보자.
head(ufc)
## plot tree species dbh.cm height.m
## 1 2 1 DF 39 20.5
## 2 2 2 WL 48 33.0
## 3 3 2 GF 52 30.0
## 4 3 5 WC 36 20.7
## 5 3 8 WC 38 22.5
## 6 4 1 WC 46 18.0
tail(ufc)
## plot tree species dbh.cm height.m
## 331 143 1 GF 28.0 21.0
## 332 143 2 GF 33.0 20.5
## 333 143 7 WC 47.8 20.5
## 334 144 1 GF 10.2 16.0
## 335 144 2 DF 31.5 22.0
## 336 144 4 WL 26.5 25.0
각 열은 고유한 이름을 가지며, 우리는 $를 사용하여
names로 해당 변수를 추출할 수 있다.
ufc$plot[1:10]
## [1] 2 2 3 3 3 4 4 5 5 6
x <- ufc$height.m
x[1:5]
## [1] 20.5 33.0 30.0 20.7 22.5
우리는 [[ ]]를 사용하여 열을 추출할 수 있다.
ufc$height.m, ufc[[5]],
ufc[["height.m"]]은 모두 동등하다.
결과는 벡터이다.
x1 <- ufc[["height.m"]] # x1은 벡터
x1[1:5]
## [1] 20.5 33.0 30.0 20.7 22.5
x2 <- ufc[[5]] # x2는 벡터
x2[1:5]
## [1] 20.5 33.0 30.0 20.7 22.5
행렬 인덱싱을 사용하여 데이터프레임의 요소를 직접 추출할 수 있다.
# the result is a vector
ufc[1:5, 5, drop=FALSE] #drop=FALSE를 써서 데이터프레임으로로 달라짐.
## height.m
## 1 20.5
## 2 33.0
## 3 30.0
## 4 20.7
## 5 22.5
데이터프레임에서 여러 변수를 선택하려면 [ ]를
사용한다.
ufc[4:5]는
ufc[c("dbh.cm", "height.m")]와 동등하다. 둘다 ufc[]안에
벡터를 넣음.
[ ]는 데이터프레임의 타입을 유지한다.
#diam.height and z are data.frame
diam.height <- ufc[4:5]
(z <- diam.height[1:5, ])
## dbh.cm height.m
## 1 39 20.5
## 2 48 33.0
## 3 52 30.0
## 4 36 20.7
## 5 38 22.5
is.data.frame(diam.height)
## [1] TRUE
# diam.height1는 data.frame이다. 하나짜리도 data.frame으로 인식한다.
diam.height1 <- ufc[5]
is.data.frame(diam.height1)
## [1] TRUE
# z1은 데이터프레임이 아닌 벡터이다. 이는 [ , ]가 단순화(중요!!)하기 때문이다.
z1 <- diam.height1[1:5, ]
is.data.frame(z1)
## [1] FALSE
[[ ]]를 사용하여 열을 선택하면 추출되는 객체의
타입이 유지된다.
반면, [ ]는 추출이 이루어지는 객체의 타입을
유지한다.
typeof(ufc)
## [1] "list"
typeof(ufc[5])
## [1] "list"
# numeric vector
typeof(ufc[[5]])
## [1] "double"
또한, [,]는 가능하다면 데이터 타입을 단순화하는 경향이
있다.
typeof(ufc[1:5, 5])
## [1] "double"
아래의 경우, 단순화는 불가능하므로 원래의 데이터프레임 타입이 유지된다.
# In this case, simplification is impossible, and original data.frame type is preserved.
typeof(ufc[1:5, 4:5])
## [1] "list"
class(ufc[1:5, 4:5])
## [1] "data.frame"
데이터프레임 내에 변수를 새로 생성하고 이름을 지정한 후 값을 할당하여 생성할 수 있다.
ufc$volume.m3 <- pi * (ufc$dbh.cm / 200)^2 * ufc$height / 2
mean(ufc$volume.m3)
## [1] 1.93294
names(df)는 데이터프레임 df의 이름을
반환한다.
df의 이름을 변경하려면 문자열 벡터를
names(df)에 전달한다.
(ufc.names <- names(ufc))
## [1] "plot" "tree" "species" "dbh.cm" "height.m" "volume.m3"
names(ufc) <- c("P", "T", "S", "D", "H", "V")
names(ufc)
## [1] "P" "T" "S" "D" "H" "V"
names(ufc) <- ufc.names
subset은 데이터프레임의 행을 선택하는 데 유용한
도구이다. * x %in% y는 논리 벡터를 반환하며, 만약
x[i]가 y에 포함되어 있으면 i번째 요소는
TRUE이다.
ufc$species %in% c("DF", "GF")
## [1] TRUE FALSE TRUE FALSE FALSE FALSE TRUE TRUE TRUE TRUE FALSE FALSE
## [13] FALSE FALSE FALSE FALSE TRUE FALSE TRUE TRUE TRUE FALSE TRUE TRUE
## [25] TRUE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE TRUE TRUE TRUE
## [37] FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE
## [49] TRUE TRUE FALSE FALSE FALSE TRUE TRUE FALSE TRUE FALSE FALSE TRUE
## [61] FALSE TRUE TRUE TRUE TRUE FALSE FALSE TRUE TRUE FALSE TRUE TRUE
## [73] FALSE TRUE FALSE TRUE FALSE TRUE FALSE FALSE FALSE FALSE TRUE TRUE
## [85] FALSE FALSE TRUE TRUE FALSE FALSE FALSE TRUE TRUE TRUE FALSE FALSE
## [97] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE
## [109] FALSE FALSE FALSE FALSE TRUE FALSE TRUE TRUE FALSE TRUE FALSE TRUE
## [121] FALSE FALSE TRUE FALSE FALSE TRUE FALSE FALSE FALSE TRUE TRUE FALSE
## [133] FALSE FALSE TRUE TRUE FALSE TRUE TRUE FALSE TRUE FALSE FALSE TRUE
## [145] TRUE TRUE FALSE TRUE FALSE TRUE FALSE FALSE FALSE FALSE TRUE TRUE
## [157] TRUE TRUE FALSE FALSE FALSE TRUE TRUE TRUE FALSE TRUE TRUE FALSE
## [169] TRUE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE FALSE TRUE FALSE
## [181] FALSE TRUE TRUE FALSE FALSE TRUE TRUE TRUE FALSE FALSE FALSE FALSE
## [193] FALSE TRUE TRUE TRUE TRUE FALSE TRUE FALSE TRUE FALSE TRUE TRUE
## [205] TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE FALSE FALSE
## [217] FALSE TRUE TRUE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE
## [229] TRUE TRUE FALSE TRUE TRUE FALSE FALSE TRUE TRUE FALSE TRUE FALSE
## [241] TRUE TRUE FALSE TRUE FALSE TRUE TRUE FALSE TRUE TRUE TRUE TRUE
## [253] FALSE TRUE FALSE TRUE FALSE FALSE FALSE TRUE TRUE FALSE FALSE FALSE
## [265] FALSE TRUE TRUE TRUE TRUE FALSE FALSE TRUE FALSE TRUE FALSE TRUE
## [277] TRUE FALSE TRUE TRUE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE
## [289] FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE
## [301] TRUE TRUE TRUE TRUE TRUE FALSE FALSE TRUE TRUE FALSE FALSE TRUE
## [313] TRUE FALSE TRUE TRUE TRUE TRUE FALSE TRUE TRUE FALSE FALSE FALSE
## [325] FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE FALSE
fir.height <- subset(ufc,
subset=species %in% c("DF", "GF"),
select = c(plot, tree, height.m, species))
head(fir.height)
## plot tree height.m species
## 1 2 1 20.5 DF
## 3 3 2 30.0 GF
## 7 4 2 17.0 DF
## 8 5 2 29.3 DF
## 9 5 4 29.0 GF
## 10 6 1 26.0 DF
write.table(x, file="", append=FALSE, sep=" ", row.names=TRUE, col.names=TRUE)
x는 작성할 데이터프레임이다.
file은 작성할 파일의 주소이다.
append는 추가 여부를 나타낸다.
sep는 값을 구분하는 데 사용되는 문자이다.
row.name은 행 이름을 첫 번째 열로 포함할지 여부를
나타낸다.
col.names는 열 이름을 첫 번째 행으로 포함할지 여부를
나타낸다.
write.table(fir.height, "data/mydf.csv", sep=",")
read_csv()와 read_tsv()는
readr 패키지의 일반 함수 read_delim()의 특별한
경우이다.
각각 쉼표로 구분된 값과 탭으로 구분된 값의 가장 일반적인 평면 파일 데이터를 읽는 데 유용하다.
아래 코드에서 ufc_tibble은 더 나은 출력 방식을
제공하는 데이터 프레임으로, 대규모 데이터 세트를 다룰 때
유용하다.
library(readr)
ufc_tibble <- read_csv("./data/ufc.csv")
## Rows: 336 Columns: 5
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (1): species
## dbl (4): plot, tree, dbh.cm, height.m
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
ufc_tibble
## # A tibble: 336 × 5
## plot tree species dbh.cm height.m
## <dbl> <dbl> <chr> <dbl> <dbl>
## 1 2 1 DF 39 20.5
## 2 2 2 WL 48 33
## 3 3 2 GF 52 30
## 4 3 5 WC 36 20.7
## 5 3 8 WC 38 22.5
## 6 4 1 WC 46 18
## 7 4 2 DF 25 17
## 8 5 2 DF 54.9 29.3
## 9 5 4 GF 51.8 29
## 10 6 1 DF 40.9 26
## # ℹ 326 more rows
벡터는 객체의 인덱스화된 집합이라는 것을 살펴 보았다.
벡터의 모든 요소는 동일한 타입이어야 하며, 숫자, 문자 또는 논리형일 수 있으며, 이를 벡터의 mode라고 한다.
리스트(list)는 인덱스화된 객체의 집합이지만, 리스트의 요소는 다른 리스트를 포함하여 서로 다른 타입일 수 있다.
리스트는 쉼표로 구분된 인수를 사용하여 c() 대신
list(...) 명령어로 생성된다.
단일 대괄호 [ ]는 서브리스트를 선택하는 데
사용된다.
이중 대괄호 [[ ]]는 단일 요소를 추출하는 데
사용된다.
(my.list <- list("one", TRUE, 3, c("f", "o", "u", "r")))
## [[1]]
## [1] "one"
##
## [[2]]
## [1] TRUE
##
## [[3]]
## [1] 3
##
## [[4]]
## [1] "f" "o" "u" "r"
str(my.list)
## List of 4
## $ : chr "one"
## $ : logi TRUE
## $ : num 3
## $ : chr [1:4] "f" "o" "u" "r"
my.list[[2]]
## [1] TRUE
mode(my.list[[2]])
## [1] "logical"
my.list[2]
## [[1]]
## [1] TRUE
mode(my.list[2])
## [1] "list"
my.list[[4]]
## [1] "f" "o" "u" "r"
my.list[[4]][1]
## [1] "f"
my.list[4][1]
## [[1]]
## [1] "f" "o" "u" "r"
리스트를 출력할 때,
R은 리스트 요소를 나타내기 위해 이중 대괄호
[[1]], [[2]], 등을 사용한다.
그런 다음 벡터 요소를 나타내기 위해 단일 대괄호
[1], [2], 등을 사용한다.
# list can contain other list
my.list2 <- list("a", c(5,6,7), my.list)
str(my.list2)
## List of 3
## $ : chr "a"
## $ : num [1:3] 5 6 7
## $ :List of 4
## ..$ : chr "one"
## ..$ : logi TRUE
## ..$ : num 3
## ..$ : chr [1:4] "f" "o" "u" "r"
my.list2[3]
## [[1]]
## [[1]][[1]]
## [1] "one"
##
## [[1]][[2]]
## [1] TRUE
##
## [[1]][[3]]
## [1] 3
##
## [[1]][[4]]
## [1] "f" "o" "u" "r"
str(my.list2[3])
## List of 1
## $ :List of 4
## ..$ : chr "one"
## ..$ : logi TRUE
## ..$ : num 3
## ..$ : chr [1:4] "f" "o" "u" "r"
#error
my.list2[3][[4]]
my.list2[[3]]
## [[1]]
## [1] "one"
##
## [[2]]
## [1] TRUE
##
## [[3]]
## [1] 3
##
## [[4]]
## [1] "f" "o" "u" "r"
my.list2[[3]][4]
## [[1]]
## [1] "f" "o" "u" "r"
my.list2[[3]][[4]]
## [1] "f" "o" "u" "r"
리스트가 생성될 때 리스트의 요소에 이름을 지정할 수 있다.
my.list <- list(first = "one", second=TRUE, third=3, fourth = c("f", "o", "u", "r"))
names(my.list)
## [1] "first" "second" "third" "fourth"
my.list$second
## [1] TRUE
리스트의 요소는 names 속성을 통해 이름을 지정할 수
있다.
names(my.list) <- c("Fi", "Se", "Th", "Fo") #새로운 이름
my.list$Se
## [1] TRUE
my.list$"Fi"
## [1] "one"
my.list[["Fi"]]
## [1] "one"
| type | 단순화(Simplifying) | 보존(Preserving) |
|---|---|---|
| vector | x[[1]] |
x[1] |
| array(matrix) | x[1, ], x[, 1] |
x[1, , drop = F], x[, 1, drop = F] |
| list | x[[1]], x$a, x[["a"]] |
x[1], x["a"] |
| data.frame | x[, 1] |
x[1, ], x[, 1, drop = F] |
데이터프레임은 리스트라는 점에 유의하라. 따라서 리스트에 대한 단순화 및 보존 규칙은 데이터프레임에도 적용된다.
많은 함수들이 출력으로 리스트 객체를 생성한다.
예를 들어, 최소제곱 회귀분석을 수행할 때, 회귀분석 결과는 리스트 객체로 반환된다.
회귀분석의 복잡한 결과를 표현하기 위해 유연한 list 객체를 활용하는 것.
이러한 객체들은 리스트 연산을 사용하여 추가적인 작업을 수행할 수 있다.
아래에서 lm 함수는 선형 회귀 모델을 적합하는
함수이다.
~ 기호는 R에서 모델을 정의할 때 사용되며 왼쪽이 종속
변수, 오른쪽이독립 변수이다.lm.xy <- lm(y~x, data=data.frame(x=1:5, y=1:5))
typeof(lm.xy)
## [1] "list"
# 요소들의 이름 출력
names(lm.xy)
## [1] "coefficients" "residuals" "effects" "rank"
## [5] "fitted.values" "assign" "qr" "df.residual"
## [9] "xlevels" "call" "terms" "model"
str 함수는 리스트나 데이터프레임을 요약하는 데
사용할 수 있다:
lm.xy$coefficients
## (Intercept) x
## 1.191616e-15 1.000000e+00str(lm.xy)
## List of 12
## $ coefficients : Named num [1:2] 1.19e-15 1.00
## ..- attr(*, "names")= chr [1:2] "(Intercept)" "x"
## $ residuals : Named num [1:5] -4.83e-16 8.35e-16 -2.10e-16 -1.54e-16 1.20e-17
## ..- attr(*, "names")= chr [1:5] "1" "2" "3" "4" ...
## $ effects : Named num [1:5] -6.71 3.16 1.11e-16 4.44e-16 8.88e-16
## ..- attr(*, "names")= chr [1:5] "(Intercept)" "x" "" "" ...
## $ rank : int 2
## $ fitted.values: Named num [1:5] 1 2 3 4 5
## ..- attr(*, "names")= chr [1:5] "1" "2" "3" "4" ...
## $ assign : int [1:2] 0 1
## $ qr :List of 5
## ..$ qr : num [1:5, 1:2] -2.236 0.447 0.447 0.447 0.447 ...
## .. ..- attr(*, "dimnames")=List of 2
## .. .. ..$ : chr [1:5] "1" "2" "3" "4" ...
## .. .. ..$ : chr [1:2] "(Intercept)" "x"
## .. ..- attr(*, "assign")= int [1:2] 0 1
## ..$ qraux: num [1:2] 1.45 1.12
## ..$ pivot: int [1:2] 1 2
## ..$ tol : num 1e-07
## ..$ rank : int 2
## ..- attr(*, "class")= chr "qr"
## $ df.residual : int 3
## $ xlevels : Named list()
## $ call : language lm(formula = y ~ x, data = data.frame(x = 1:5, y = 1:5))
## $ terms :Classes 'terms', 'formula' language y ~ x
## .. ..- attr(*, "variables")= language list(y, x)
## .. ..- attr(*, "factors")= int [1:2, 1] 0 1
## .. .. ..- attr(*, "dimnames")=List of 2
## .. .. .. ..$ : chr [1:2] "y" "x"
## .. .. .. ..$ : chr "x"
## .. ..- attr(*, "term.labels")= chr "x"
## .. ..- attr(*, "order")= int 1
## .. ..- attr(*, "intercept")= int 1
## .. ..- attr(*, "response")= int 1
## .. ..- attr(*, ".Environment")=<environment: R_GlobalEnv>
## .. ..- attr(*, "predvars")= language list(y, x)
## .. ..- attr(*, "dataClasses")= Named chr [1:2] "numeric" "numeric"
## .. .. ..- attr(*, "names")= chr [1:2] "y" "x"
## $ model :'data.frame': 5 obs. of 2 variables:
## ..$ y: int [1:5] 1 2 3 4 5
## ..$ x: int [1:5] 1 2 3 4 5
## ..- attr(*, "terms")=Classes 'terms', 'formula' language y ~ x
## .. .. ..- attr(*, "variables")= language list(y, x)
## .. .. ..- attr(*, "factors")= int [1:2, 1] 0 1
## .. .. .. ..- attr(*, "dimnames")=List of 2
## .. .. .. .. ..$ : chr [1:2] "y" "x"
## .. .. .. .. ..$ : chr "x"
## .. .. ..- attr(*, "term.labels")= chr "x"
## .. .. ..- attr(*, "order")= int 1
## .. .. ..- attr(*, "intercept")= int 1
## .. .. ..- attr(*, "response")= int 1
## .. .. ..- attr(*, ".Environment")=<environment: R_GlobalEnv>
## .. .. ..- attr(*, "predvars")= language list(y, x)
## .. .. ..- attr(*, "dataClasses")= Named chr [1:2] "numeric" "numeric"
## .. .. .. ..- attr(*, "names")= chr [1:2] "y" "x"
## - attr(*, "class")= chr "lm"
R에는 리스트나 데이터프레임의 모든 또는 선택된 요소에 함수를 쉽게 적용할 수 있는 여러 함수가 있다.
tapply 함수는 데이터의 부분 집합에 함수를 벡터화하여
적용할 수 있게 해준다.
tapply(X, INDEX, FUN, ...)
X: 적용할 대상 벡터이다.
INDEX: 요소를 그룹화하는 데 사용되는 팩터이며,
X와 같은 길이를 가져야 한다. (INDEX가 팩터가
아닌 경우 자동으로 팩터로 변환된다.)
FUN: 적용할 함수이다. 이는 INDEX의 단일
레벨에 해당하는 X의 서브벡터에 적용된다.
tapply는 SQL의 groupby와
summary 함수 조합과 유사하게 작동한다.
INDEX는 groupby를 나타내고,
FUN은 요약 함수를 나타낸다.
tapply를 사용하여 종(species)별로 평균 키(height)를
구하는 방법은 다음과 같다:
ufc <- read.csv("./data/ufc.csv")
ufc$volume.m3 <- pi * (ufc$dbh.cm / 200)^2 * ufc$height / 2
tapply(ufc$height.m, ufc$species, mean)
## DF GF WC WL
## 25.30000 24.34322 23.48777 25.47273
tapply(ufc$height.m, ufc$species, mean)
## DF GF WC WL
## 25.30000 24.34322 23.48777 25.47273
mean(ufc[ufc$species == "DF", 'height.m']) #위의 DF를 나타냄!
## [1] 25.3
결과 반올림:
round(tapply(ufc$height.m, ufc$species, mean), digits=1)
## DF GF WC WL
## 25.3 24.3 23.5 25.5
각 종(species)별로 샘플 수를 확인하는 방법은 다음과 같다:
tapply(ufc$species, ufc$species, length)
## DF GF WC WL
## 57 118 139 22
# the same result
tapply(ufc$height.m, ufc$species, length)
## DF GF WC WL
## 57 118 139 22
tapply(ufc$height.m, ufc$species, max)
## DF GF WC WL
## 42.0 47.0 40.0 42.5
tapply를 사용하여 벡터의 요소 수를 계산할 수 있다:
x <- c(1,2,3,4,5,4,6,2,5,6,5,3,4,1,4,5,6,7,2,2,6,7,9,3,5)
tapply(X = x, INDEX = x, FUN = length) #1이 몇개? 2가 몇개?~~
## 1 2 3 4 5 6 7 9
## 2 4 3 4 5 4 2 1
위 내용은 다음과 거의 동일하다:
table(x)
## x
## 1 2 3 4 5 6 7 9
## 2 4 3 4 5 4 2 1
y <- x %% 2
tapply(X = x, INDEX = y, FUN = length)
## 0 1
## 12 13
y <- x %% 2
tapply(X = x, INDEX = y, FUN = max)
## 0 1
## 6 9
lapply(X, FUN, ...)는 리스트 X의 각
요소에 함수 FUN을 적용하고 리스트로 반환한다.
sapply(X, FUN, ...)는 X의 각 요소에
함수 FUN을 적용한다. X는 리스트나 벡터일 수
있으며, 기본적으로 결과를 벡터나 행렬로 반환하려고 시도한다. 만약 이것이
의미가 없다면, 리스트로 반환한다.
나무의 평균 직경, 높이 및 부피를 구하려면:
ufc[4:6]
## dbh.cm height.m volume.m3
## 1 39.0 20.5 1.22445537
## 2 48.0 33.0 2.98576966
## 3 52.0 30.0 3.18557495
## 4 36.0 20.7 1.05350168
## 5 38.0 22.5 1.27587932
## 6 46.0 18.0 1.49571226
## 7 25.0 17.0 0.41724277
## 8 54.9 29.3 3.46794495
## 9 51.8 29.0 3.05574706
## 10 40.9 26.0 1.70796847
## 11 29.0 22.0 0.72657184
## 12 29.4 32.0 1.08618681
## 13 68.5 26.0 4.79086989
## 14 63.0 33.0 5.14345476
## 15 46.6 27.5 2.34511645
## 16 55.3 30.0 3.60272740
## 17 46.2 31.3 2.62354293
## 18 27.1 27.0 0.77868576
## 19 40.0 27.0 1.69646003
## 20 36.3 28.0 1.44887583
## 21 42.0 33.0 2.28597989
## 22 37.5 29.8 1.64565459
## 23 38.3 27.1 1.56108562
## 24 22.3 21.5 0.41986345
## 25 22.5 22.6 0.44929684
## 26 21.8 18.0 0.33592736
## 27 15.1 15.5 0.13878594
## 28 23.0 20.0 0.41547563
## 29 32.0 22.5 0.90477868
## 30 52.5 29.0 3.13889285
## 31 10.5 5.0 0.02164754
## 32 75.0 32.0 7.06858347
## 33 89.5 35.0 11.00966237
## 34 30.0 25.0 0.88357293
## 35 32.0 31.0 1.24658396
## 36 29.5 27.0 0.92271521
## 37 42.5 22.5 1.59595361
## 38 83.0 35.0 9.46856391
## 39 39.0 24.0 1.43350873
## 40 25.0 28.0 0.68722339
## 41 22.5 26.0 0.51689017
## 42 21.0 22.5 0.38965566
## 43 12.5 14.0 0.08590292
## 44 24.0 19.0 0.42976988
## 45 27.5 23.0 0.68305097
## 46 32.5 26.5 1.09918927
## 47 11.5 8.0 0.04154756
## 48 36.5 31.5 1.64799606
## 49 28.2 25.0 0.78072504
## 50 19.8 16.0 0.24632600
## 51 21.5 17.5 0.31766901
## 52 38.9 30.0 1.78270853
## 53 44.3 37.5 2.89000508
## 54 26.3 28.0 0.76055288
## 55 34.3 23.5 1.08571538
## 56 26.2 21.0 0.56608515
## 57 40.5 22.0 1.41707427
## 58 19.9 17.0 0.26437170
## 59 14.6 11.0 0.09207851
## 60 39.8 36.5 2.27048634
## 61 40.1 37.5 2.36799019
## 62 23.0 13.0 0.27005916
## 63 37.1 21.0 1.13508138
## 64 21.5 19.0 0.34489779
## 65 14.8 15.0 0.12902521
## 66 68.6 28.0 5.17447328
## 67 13.9 12.5 0.09484174
## 68 18.5 19.0 0.25536240
## 69 14.2 16.0 0.12669415
## 70 48.7 25.0 2.32840121
## 71 52.7 30.0 3.27191770
## 72 32.2 26.0 1.05863190
## 73 64.0 27.0 4.34293768
## 74 58.5 34.0 4.56930907
## 75 24.3 13.0 0.30145034
## 76 29.6 32.0 1.10101513
## 77 43.0 29.0 2.10569175
## 78 52.2 31.0 3.31713071
## 79 27.2 23.0 0.66822932
## 80 34.0 23.0 1.04410832
## 81 40.4 26.0 1.66646411
## 82 11.1 9.5 0.04596523
## 83 20.7 25.0 0.42066907
## 84 28.3 31.0 0.97497718
## 85 49.6 23.0 2.22203592
## 86 44.9 25.0 1.97921319
## 87 42.5 30.0 2.12793815
## 88 71.9 32.0 6.49632352
## 89 56.5 27.5 3.44738252
## 90 31.1 25.0 0.94955620
## 91 42.5 27.0 1.91514433
## 92 35.2 27.0 1.31373865
## 93 42.1 30.0 2.08807134
## 94 14.0 20.0 0.15393804
## 95 17.7 19.0 0.23375452
## 96 33.5 20.0 0.88141309
## 97 40.5 22.0 1.41707427
## 98 29.5 28.0 0.95688985
## 99 69.0 30.0 5.60892098
## 100 46.5 26.0 2.20769533
## 101 42.5 29.0 2.05700688
## 102 30.5 21.0 0.76714747
## 103 30.5 25.0 0.91327080
## 104 37.8 28.0 1.57109164
## 105 49.7 30.0 2.91000622
## 106 37.7 28.0 1.56278998
## 107 32.5 25.0 1.03697101
## 108 26.2 23.0 0.61999802
## 109 31.0 26.0 0.98119793
## 110 38.5 27.0 1.57161118
## 111 94.0 36.0 12.49160071
## 112 101.5 39.0 15.77816805
## 113 35.0 34.0 1.63559168
## 114 31.5 24.5 0.95465638
## 115 59.0 31.2 4.26499477
## 116 35.0 34.0 1.63559168
## 117 31.5 24.5 0.95465638
## 118 59.0 31.2 4.26499477
## 119 60.2 32.0 4.55410298
## 120 18.0 22.0 0.27991591
## 121 47.1 30.0 2.61350271
## 122 63.7 28.5 4.54133574
## 123 63.8 34.0 5.43475737
## 124 12.5 10.0 0.06135923
## 125 15.5 11.5 0.10849785
## 126 45.5 31.5 2.56090361
## 127 60.0 33.0 4.66526509
## 128 20.0 17.5 0.27488936
## 129 32.0 30.0 1.20637158
## 130 42.0 30.5 2.11279960
## 131 25.5 22.5 0.57454330
## 132 27.9 15.0 0.45852134
## 133 52.8 31.5 3.44856395
## 134 23.4 18.0 0.38704736
## 135 47.7 31.0 2.76986331
## 136 61.3 25.0 3.68910353
## 137 37.7 24.2 1.35069705
## 138 16.5 17.2 0.18388920
## 139 39.7 25.3 1.56589061
## 140 80.4 32.0 8.12310303
## 141 99.8 42.0 16.42745396
## 142 45.6 32.5 2.65382898
## 143 38.7 27.0 1.58798202
## 144 50.2 37.0 3.66158436
## 145 68.3 39.0 7.14440227
## 146 42.2 32.8 2.29381628
## 147 34.4 25.7 1.19429027
## 148 18.5 20.2 0.27149055
## 149 54.3 30.5 3.53150141
## 150 86.1 40.2 11.70286625
## 151 51.9 32.5 3.43777906
## 152 25.8 22.8 0.59598337
## 153 40.0 21.1 1.32575210
## 154 37.4 20.0 1.09858354
## 155 10.4 16.5 0.07008265
## 156 24.8 19.0 0.45889872
## 157 33.5 27.5 1.21194300
## 158 25.0 23.5 0.57677678
## 159 14.1 14.0 0.10930151
## 160 15.7 17.5 0.16939369
## 161 25.0 19.0 0.46633016
## 162 19.7 16.5 0.25146427
## 163 37.2 27.0 1.46726828
## 164 30.0 28.0 0.98960169
## 165 47.0 30.0 2.60241681
## 166 19.1 14.5 0.20772780
## 167 46.3 30.0 2.52547528
## 168 57.5 3.4 0.44144286
## 169 78.0 42.0 10.03456109
## 170 58.0 33.5 4.42548303
## 171 28.9 20.5 0.67237171
## 172 49.6 27.0 2.60847695
## 173 52.8 28.5 3.12012929
## 174 44.5 27.0 2.09963436
## 175 15.8 17.0 0.16665678
## 176 35.7 34.5 1.72669413
## 177 25.3 27.5 0.69124758
## 178 14.8 14.5 0.12472437
## 179 30.5 23.5 0.85847455
## 180 12.2 14.0 0.08182906
## 181 38.2 23.5 1.34664919
## 182 27.5 23.5 0.69789990
## 183 14.6 23.5 0.19671318
## 184 54.5 26.5 3.09099829
## 185 18.2 19.0 0.24714752
## 186 32.2 23.0 0.93648207
## 187 35.0 23.0 1.10642966
## 188 50.2 30.0 2.96885218
## 189 10.8 10.0 0.04580442
## 190 14.4 10.0 0.08143008
## 191 22.6 14.0 0.28080498
## 192 40.5 18.0 1.15942440
## 193 43.7 27.0 2.02482048
## 194 64.4 42.0 6.84039075
## 195 29.0 23.0 0.75959783
## 196 52.5 27.0 2.92241748
## 197 24.8 24.0 0.57966154
## 198 46.6 25.0 2.13192404
## 199 28.3 21.5 0.67619385
## 200 15.3 13.0 0.11950501
## 201 58.8 25.0 3.39433378
## 202 59.5 23.0 3.19758173
## 203 65.6 35.0 5.91473932
## 204 10.5 9.5 0.04113032
## 205 19.6 18.5 0.27908967
## 206 44.1 30.0 2.29117530
## 207 24.5 22.0 0.51857877
## 208 24.8 21.0 0.50720385
## 209 50.6 32.0 3.21744327
## 210 45.3 30.0 2.41756158
## 211 17.1 12.0 0.13779497
## 212 69.0 40.0 7.47856131
## 213 71.6 35.0 7.04618391
## 214 41.5 28.0 1.89371278
## 215 45.5 33.5 2.72350067
## 216 72.5 35.5 7.32764215
## 217 44.3 20.5 1.57986944
## 218 15.5 14.5 0.13680163
## 219 14.0 9.0 0.06927212
## 220 47.3 30.0 2.63574519
## 221 43.3 29.5 2.17198936
## 222 70.8 42.5 8.36595128
## 223 79.8 31.0 7.75224273
## 224 22.0 18.0 0.34211944
## 225 44.0 32.0 2.43284935
## 226 55.8 26.0 3.17908128
## 227 60.7 26.0 3.76192918
## 228 12.1 10.5 0.06036983
## 229 30.0 17.0 0.60082959
## 230 47.6 25.5 2.26889277
## 231 30.9 17.0 0.63742012
## 232 33.0 29.0 1.24018297
## 233 51.5 29.5 3.07253161
## 234 50.8 28.5 2.88823263
## 235 53.0 23.0 2.53711096
## 236 43.0 18.5 1.34328611
## 237 46.0 28.0 2.32666352
## 238 59.4 33.3 4.61399383
## 239 33.8 24.1 1.08121068
## 240 20.1 16.1 0.25543351
## 241 26.2 14.5 0.39086832
## 242 10.8 14.8 0.06779054
## 243 51.2 27.0 2.77948012
## 244 43.5 26.4 1.96174397
## 245 37.1 28.8 1.55668304
## 246 42.1 32.4 2.25511705
## 247 78.5 37.0 8.95366669
## 248 10.1 9.0 0.03605331
## 249 49.4 23.6 2.26165203
## 250 60.7 30.0 4.34068752
## 251 46.3 30.0 2.52547528
## 252 55.1 18.0 2.14602901
## 253 65.4 35.5 5.96271066
## 254 23.9 23.2 0.52040765
## 255 28.4 19.3 0.61129927
## 256 19.7 11.0 0.16764285
## 257 28.2 20.5 0.64019454
## 258 22.2 18.7 0.36191571
## 259 11.9 11.5 0.06395163
## 260 24.5 23.8 0.56100794
## 261 31.4 27.0 1.04540108
## 262 12.0 12.8 0.07238229
## 263 15.9 12.5 0.12409782
## 264 27.0 17.0 0.48667197
## 265 27.7 20.5 0.61769386
## 266 43.8 17.9 1.34853163
## 267 39.7 19.5 1.20691174
## 268 47.5 27.0 2.39227372
## 269 49.8 24.5 2.38607810
## 270 42.3 30.5 2.14309025
## 271 48.8 24.5 2.29121379
## 272 81.2 47.0 12.16941782
## 273 45.0 28.0 2.22660379
## 274 56.5 30.0 3.76078093
## 275 53.0 23.5 2.59226554
## 276 52.2 35.0 3.74514758
## 277 34.3 25.5 1.17811668
## 278 34.1 24.5 1.11875433
## 279 23.9 21.0 0.47105865
## 280 41.3 26.0 1.74153953
## 281 19.7 18.0 0.27432466
## 282 15.0 16.5 0.14578953
## 283 43.2 24.0 1.75888976
## 284 26.8 22.0 0.62051481
## 285 28.6 29.5 0.94757582
## 286 30.2 29.5 1.05656395
## 287 31.4 28.0 1.08411964
## 288 26.6 19.0 0.52793051
## 289 34.1 25.0 1.14158605
## 290 33.0 17.0 0.72700381
## 291 26.7 15.0 0.41992687
## 292 23.4 20.0 0.43005262
## 293 31.2 19.0 0.72631109
## 294 35.2 24.5 1.19209618
## 295 25.7 18.0 0.46687287
## 296 16.3 9.0 0.09390260
## 297 40.1 19.5 1.23135490
## 298 17.6 16.5 0.20071007
## 299 42.5 28.0 1.98607561
## 300 31.4 23.0 0.89052685
## 301 27.1 21.0 0.60564448
## 302 40.0 21.0 1.31946891
## 303 51.3 31.0 3.20373296
## 304 28.4 23.0 0.72849135
## 305 39.3 25.0 1.51629951
## 306 33.7 17.0 0.75817351
## 307 21.3 15.5 0.27615365
## 308 20.1 16.0 0.25384697
## 309 45.4 25.0 2.02353910
## 310 29.7 20.0 0.69279187
## 311 22.8 12.0 0.24496883
## 312 29.2 23.0 0.77011117
## 313 38.3 24.0 1.38251125
## 314 17.4 12.0 0.14267229
## 315 23.9 17.5 0.39254887
## 316 18.9 16.0 0.22444166
## 317 20.5 13.0 0.21454133
## 318 21.0 18.5 0.32038355
## 319 55.5 27.5 3.32643120
## 320 16.4 13.0 0.13730645
## 321 56.5 37.0 4.63829648
## 322 37.3 20.5 1.12003453
## 323 20.7 14.0 0.23557468
## 324 44.6 28.5 2.22625272
## 325 36.7 25.0 1.32230617
## 326 44.5 27.0 2.09963436
## 327 31.6 20.5 0.80387387
## 328 28.3 24.0 0.75482104
## 329 52.2 27.5 2.94261596
## 330 22.5 20.5 0.40754802
## 331 28.0 21.0 0.64653977
## 332 33.0 20.5 0.87668106
## 333 47.8 20.5 1.83937187
## 334 10.2 16.0 0.06537026
## 335 31.5 22.0 0.85724246
## 336 26.5 25.0 0.68943233
lapply(ufc[4:6], mean) # return a list
## $dbh.cm
## [1] 37.41369
##
## $height.m
## [1] 24.2256
##
## $volume.m3
## [1] 1.93294
sapply(ufc[4:6], mean) # return a vector
## dbh.cm height.m volume.m3
## 37.41369 24.22560 1.93294
result <- rep(0,3) #뭔가 중요할듯.
for (i in 4:6){
result[i] <- mean(ufc[[i]])
}
result
## [1] 0.00000 0.00000 0.00000 37.41369 24.22560 1.93294
result <- list()
for (i in 4:6){
result[[i-1]] <- mean(ufc[[i]])
}
result
## [[1]]
## NULL
##
## [[2]]
## NULL
##
## [[3]]
## [1] 37.41369
##
## [[4]]
## [1] 24.2256
##
## [[5]]
## [1] 1.93294
Simple example:
sapply(1:3, function(x) x^2)
## [1] 1 4 9
lapply(1:3, function(x) x^2)
## [[1]]
## [1] 1
##
## [[2]]
## [1] 4
##
## [[3]]
## [1] 9
df <- data.frame(replicate(6, sample(c(1:10, -99), 6, rep = TRUE)))
names(df) <- letters[1:6]
df
## a b c d e f
## 1 8 -99 8 5 5 3
## 2 2 6 8 6 9 7
## 3 5 1 4 1 2 7
## 4 4 9 5 10 10 1
## 5 6 10 6 3 5 4
## 6 6 6 9 -99 1 10
모든 -99를 NA로 대체하려고 한다면
fix_missing <- function(x) {
x[x == -99] <- NA
x
}
df[] <- lapply(df, fix_missing) #list to data.frame, use df[]
df
## a b c d e f
## 1 8 NA 8 5 5 3
## 2 2 6 8 6 9 7
## 3 5 1 4 1 2 7
## 4 4 9 5 10 10 1
## 5 6 10 6 3 5 4
## 6 6 6 9 NA 1 10
sapply(df, fix_missing)
## a b c d e f
## [1,] 8 NA 8 5 5 3
## [2,] 2 6 8 6 9 7
## [3,] 5 1 4 1 2 7
## [4,] 4 9 5 10 10 1
## [5,] 6 10 6 3 5 4
## [6,] 6 6 9 NA 1 10
More about apply : http://adv-r.had.co.nz/Functional-programming.html
함수 인수에서 세 개의 점으로 이루어진 생략 기호 ...는
가변 길이 인수 목록을 받는 데 사용된다.
paste 함수에서는 가변 개수의 인수를 넣을 수
있다. ?paste를 통해 확인할 수 있다....를 처리하기 위해서는, 함수 내에서 이를 리스트로
변환하여 사용한다.
addemup <- function(x, ...){
args <- list(...)
for (a in args) x <- x + a
x
}
addemup(1, 1)
## [1] 2
addemup(1, 2, 3, 4, 5)
## [1] 15
reverse_paste0 함수는 입력된 인수를 반대 순서로 결합하는
함수이다.
reverse_paste0 <- function(...){
result <- ""
args <- list(...)
for (i in length(args):1){
result <- paste0(result, args[i])
}
result
}
reverse_paste0("a", "b", "c")
## [1] "cba"
reverse_paste0("a", "b", "c", "d", "e")
## [1] "edcba"