R 테이블 데이터프레임 - R teibeul deiteopeuleim

R 데이터 처리 & 분석

R 데이터프레임(data.frame)의 모든 것(행추가,열추가,삭제)

love R 2020. 1. 14. 00:54

R 데이터프레임(data.frame)의 모든 것(행추가,열추가)

이번에는 R 데이터프레임에 대해 알아볼 것인데요.
데이터프레임은 R에서 가장 많이 쓰고 중요한 데이터 구조입니다.
지난 포스팅에서 데이터프레임에 대해 간단하게 다루었는데, 이번 글은 데이터프레임만을 다루는 주제로 정했습니다.

R 테이블 데이터프레임 - R teibeul deiteopeuleim

2. 데이터프레임 행(row) 추가

2.1. 행 추가 방법

이제 위에서 만든 test라는 데이터에 행을 추가할 것입니다.

변수에 4와 11을 각각 추가하여 네번째 행을 만들어봅시다.

# 4행에 데이터 추가하기
# test[4, ] 은 test의 4번째 행을 가리키는 표현입니다.

test[4, ] <- c(4, 11)
test

R 테이블 데이터프레임 - R teibeul deiteopeuleim

3. 데이터프레임 열(column) 추가

데이터프레임의 열 추가도 위와 비슷한 방식으로 하면 됩니다.

test데이터에 var100 이라는 변수에 100, 200, 300, 400을 추가하고 싶습니다.

test[ , "var100" ] <- c(100,200,300,400)
test

R 테이블 데이터프레임 - R teibeul deiteopeuleim

4. 데이터프레임 열 삭제

변수 생성이 있으면 삭제하는 방법도 있습니다.
test 데이터에서 var1 변수를 제거하려면 -색인명을 붙여주면 됩니다.

# test[  , -1] 은 첫번째 열을 삭제를 의미함
test[  ,-1]

R 테이블 데이터프레임 - R teibeul deiteopeuleim

위와 같은 방법도 있고 남겨놓을 열을 선택하는 방법도 있습니다.

다수의 열을 남겨 놓을 때는 벡터를 이용합니다!

# 두번째, 세번째 열을 선택
test[  ,c(2,3) ]

R 테이블 데이터프레임 - R teibeul deiteopeuleim

# 연속적으로 열을 선택 또는 삭제는 : 를 이용할 수 있음
test[  , 2:3]

R 테이블 데이터프레임 - R teibeul deiteopeuleim

4. 데이터프레임 행 삭제

행 삭제도 위와 같은 방식으로 비슷하게 진행합니다.

# test[ -1, ] 은 첫번째 행 삭제를 의미함
test[ -1, ]

R 테이블 데이터프레임 - R teibeul deiteopeuleim

# test[ c(2,3,4) , ] 은 2~4행 선택을 의미함
test[ c(2,3,4), ]

R 테이블 데이터프레임 - R teibeul deiteopeuleim


# 연속적으로 행을 선택 또는 삭제는 : 를 이용할 수 있음
test[2:4, ]

R 테이블 데이터프레임 - R teibeul deiteopeuleim

행/열 추가 및 삭제는 dplyr 패키지를 이용하거나 subset 함수를 이용하여 할 수도 있습니다.

포스팅 해놓았으니 관심있으신 분들은 함께 봐주세요.

다른 함수를 이용해 행/열을 다룰 수 있지만, 이번에 소개한 방법이 가장 기본이 되는 것이기 때문에 꼭 숙지하시기 바랍니다!

냉철하마 2021. 4. 24. 18:00

참고도서: R 통계 프로그래밍의 이해 - 차영준, 박진표 (자유아카데미) 2장

www.yes24.com/Product/Goods/68712840

R 통계 프로그래밍의 이해

'최근에 빅데이터와 관련된 용어들이 많이 사용되고 있다. 인공지능, 머신러닝, 데이터 과학, 데이터 과학자, 4차 산업혁명 등과 같은 단어들을 많이 접하게 된다. 이처럼 많은 사람들이 빅데이

www.yes24.com

R 테이블 데이터프레임 - R teibeul deiteopeuleim

> #### 2.6 데이터 프레임 ####

>

> # 2.6.1 data.frame() 함수를 이용한 데이터 프레임의 생성 #

> name <- c("Cha", "Park", "Kim", "Lee", "Jung")

> gender <- c("M","F","F","F","M")

> toeic <- c(900,850,990,690,730)

> gpa <- c(4.5, 3.8, 4.5, 3.2, 3.1)

> student.1 <- data.frame(gender, toeic, gpa)

> student.1

  gender toeic gpa

1 M 900 4.5

2 F 850 3.8

3 F 990 4.5

4 F 690 3.2

5 M 730 3.1

> str(student.1) ## 문자열 벡터인 gender가 팩터를 변경됨을 확인

'data.frame':5 obs. of 3 variables:

$ gender: chr "M" "F" "F" "F" ...

$ toeic : num 900 850 990 690 730

$ gpa : num 4.5 3.8 4.5 3.2 3.1

>

> # 2.6.2 data.frame() 함수의 인수 stringsAsFactors #

> student.2 <- data.frame(name, toeic, gpa, stringsAsFactors = FALSE)

> student.2

  name toeic gpa

1 Cha 900 4.5

2 Park 850 3.8

3 Kim 990 4.5

4 Lee 690 3.2

5 Jung 730 3.1

> str(student.2) ## 팩터로 변경하시겠습니까? -> 아니요

'data.frame':5 obs. of 3 variables:

$ name : chr "Cha" "Park" "Kim" "Lee" ...

$ toeic: num 900 850 990 690 730

$ gpa : num 4.5 3.8 4.5 3.2 3.1

> # R 4버전 이후로 stringsAsFactors = FALSE가 기본값(default)로 전환

> # R 3버전은 TRUE가 default: 변수의 팩터변환을 막으려면 stringsAsFactors=FALSE 인수 입력 필수

>

> #data.frame() 함수에서 인수 stringsAsFactors의 적용 시 유의사항

> student.3 <- data.frame(name, gender, toeic, gpa, stringsAsFactors = FALSE)

> str(student.3) ## 문자형의 모든 벡터가 팩터로 변경되지 않고 그대로 남음

  'data.frame':5 obs. of 4 variables:

$ name : chr "Cha" "Park" "Kim" "Lee" ...

$ gender: chr "M" "F" "F" "F" ...

$ toeic : num 900 850 990 690 730

$ gpa : num 4.5 3.8 4.5 3.2 3.1

> student.3$gender <- factor(student.3$gender)

> student.3$gender

[1] M F F F M

Levels: F M

> str(student.3) ## , gender 변수가 범주형 데이터이므로 factor() 함수를 이용하여 팩터로 변경하여야 함

  'data.frame':5 obs. of 4 variables:

$ name : chr "Cha" "Park" "Kim" "Lee" ...

$ gender: Factor w/ 2 levels "F","M": 2 1 1 1 2

$ toeic : num 900 850 990 690 730

$ gpa : num 4.5 3.8 4.5 3.2 3.1

>

> #data.frame() 에서 함수 I() 활용

> student.4 <- data.frame(name=I(name), gender, toeic, gpa)

> student.4 ## 함수 I()를 이용해 특수한 변수들을 문자형 벡터로 남길 수 있음

  name gender toeic gpa

1 Cha M 900 4.5

2 Park F 850 3.8

3 Kim F 990 4.5

4 Lee F 690 3.2

5 Jung M 730 3.1

> mode(student.4$name) ## 문자형 벡터의 유형 -> "character"

[1] "character"

> mode(student.4$gender) ## 팩터의 유형 -> "numeric" (Factor 아님)

[1] "character"

> str(student.4)

  'data.frame':5 obs. of 4 variables:

$ name : 'AsIs' chr "Cha" "Park" "Kim" "Lee" ...

$ gender: chr "M" "F" "F" "F" ...

$ toeic : num 900 850 990 690 730

$ gpa : num 4.5 3.8 4.5 3.2 3.1

>

> #data.frame() 함수의 인수 row.names

> student.5 <- data.frame(gender, toeic, gpa, row.names=name)

> student.5 ## 인수 row.names: 행 이름 지정

gender toeic gpa

Cha M 900 4.5

Park F 850 3.8

Kim F 990 4.5

Lee F 690 3.2

Jung M 730 3.1

>

> #data.frame()에서 순환법칙

> w <- 1004; x <- 1:6; y <- c(100,200); z <- 1:5

> data.frame(w,x) ## 두 벡터의 길이가 다른 경우, 길이가 짧은 벡터의 원소를 순환 반복

       w x

1 1004 1

2 1004 2

3 1004 3

4 1004 4

5 1004 5

6 1004 6

> data.frame(x,y) ## 길이가 긴 원소와 짝을 맞춰 데이터 프레임 생성

   x   y

1 1 100

2 2 200

3 3 100

4 4 200

5 5 100

6 6 200

> data.frame(x,z) ## , 긴 벡터의 길이가 짧은 벡터의 길이의 배수가 아닐 경우

Error in data.frame(x, z) :

arguments imply differing number of rows: 6, 5

> data.frame(y,z) ## R에서 경고 문구를 내보냄

Error in data.frame(y, z) :

arguments imply differing number of rows: 2, 5

>

>

> #### 2.7 리스트 ####

>

> #리스트의 생성

> a <- c(999, 888, 777)

> b <- matrix(1:9, nrow=3)

> c <- data.frame(age = c(11,22,33,44,55), gender=c("M","F","M","F","M"))

> dataList <- list(aVec=a, bMat=b, cDataFr=c) ## a변수를 aVec으로, b변수를 bMet, c변수를 cDataFr로 하는 리스트 생성

> dataList

$aVec

[1] 999 888 777

$bMat

[,1] [,2] [,3]

[1,] 1 4 7

[2,] 2 5 8

[3,] 3 6 9

$cDataFr

age gender

1 11 M

2 22 F

3 33 M

4 44 F

5 55 M

>

> #리스트의 성분 선택

> dataList[[1]] ## 리스트의 첫번째 성분(a) 전체 추출

[1] 999 888 777

> dataList[["aVec"]]

[1] 999 888 777

> dataList$aVec

[1] 999 888 777

> dataList[[3]] ## 리스트의 세번째 성분(c) 전체 추출

  age gender

1 11 M

2 22 F

3 33 M

4 44 F

5 55 M

> dataList[[1]][2] ## 리스트의 첫번째 성분 중 2번째 원소 추출

[1] 888

> dataList[["aVec"]][2]

[1] 888

> dataList$aVec[2]

[1] 888

>

> #리스트의 첨자 []와 이중 첨자 [[]]의 차이점

> dataList[[3]] ## [[]] 출력 결과에 대한 데이터 구조: 데이터 프레임

  age gender

1 11 M

2 22 F

3 33 M

4 44 F

5 55 M

> class(dataList[[3]])

[1] "data.frame"

> dataList[3] ## [] 출력 결과에 대한 데이터 구조: 리스트

$cDataFr

  age gender

1 11 M

2 22 F

3 33 M

4 44 F

5 55 M

> class(dataList[3])

[1] "list"

>

> #리스트의 성분 이름 지정

> a <- c(999,888,777)

> b <- matrix(1:9, nrow=3)

> c <- data.frame(age = c(11,22,33,44,55), gender=c("M","F","M","F","M"))

> dataL <- list(a,b,c)

> dataL

[[1]]

[1] 999 888 777

[[2]]

[,1] [,2] [,3]

[1,] 1 4 7

[2,] 2 5 8

[3,] 3 6 9

[[3]]

age gender

1 11 M

2 22 F

3 33 M

4 44 F

5 55 M

>

> names(dataL) <- c("num","mat","datafr")

> dataL

$num

[1] 999 888 777

$mat

[,1] [,2] [,3]

[1,] 1 4 7

[2,] 2 5 8

[3,] 3 6 9

$datafr

age gender

1 11 M

2 22 F

3 33 M

4 44 F

5 55 M

>

> #리스트의 성분 삭제

> dataL["mat"] <- NULL

> dataL

$num

[1] 999 888 777

$datafr

age gender

1 11 M

2 22 F

3 33 M

4 44 F

5 55 M

>

> #리스트를 벡터로 변환

> A <- c(11,22,33)

> B <- c("동백꽃", "진달래꽃", "연산홍", "목련화", "수선화")

> C <- c("M","F","M","M","F","M")

> dataABC <- list(A,B,C)

> dataABC

[[1]]

[1] 11 22 33

[[2]]

[1] "동백꽃" "진달래꽃" "연산홍" "목련화" "수선화"

[[3]]

[1] "M" "F" "M" "M" "F" "M"

>

> dataUnABC <- unlist(dataABC) ## unlist() 함수: 리스트를 벡터로 변환

> dataUnABC

[1] "11" "22" "33" "동백꽃" "진달래꽃" "연산홍" "목련화" "수선화"

[9] "M" "F" "M" "M" "F" "M"

> is.vector(dataUnABC)

[1] TRUE

>

>

> #### 2.8 데이터 테이블 ####

> #데이터 테이블 생성

> install.packages("data.table") ## data.table 함수 사용 위해 data.table 패키지 설치

> library(data.table) ## 패키지(library) 저장을 위해 설치(install)와 함께 사용

> dataTbl <- data.table(x=1:6, y=c(2,4,6), z=rep(c("C","B","A"), each=2))

> dataTbl ## 데이터 테이블 생성

x y z

1: 1 2 C

2: 2 4 C

3: 3 6 B

4: 4 2 B

5: 5 4 A

6: 6 6 A

> class(dataTbl) ## 데이터 테이블의 class = data.tabledata.frame 두 개 모두 가짐

[1] "data.table" "data.frame"

>

> dataFrm <- data.frame(x=1:6, y=c(2,4,6), z=rep(c("C","B","A"), each=2))

> dataFrm ## 데이터 프레임 생성

x y z

1 1 2 C

2 2 4 C

3 3 6 B

4 4 2 B

5 5 4 A

6 6 6 A

> dataTbl.2 <- as.data.table(dataFrm) ## 데이터 프레임을 데이터 테이블로 변환

> dataTbl.2

x y z

1: 1 2 C

2: 2 4 C

3: 3 6 B

4: 4 2 B

5: 5 4 A

6: 6 6 A

> dataTbl.3 <- data.table(dataFrm) ## 'as.' 없이 "data.table"로도 변환 가능

> dataTbl.3

x y z

1: 1 2 C

2: 2 4 C

3: 3 6 B

4: 4 2 B

5: 5 4 A

6: 6 6 A

> class(dataTbl.2) ## 데이터 테이블이 데이터 프레임에 포함되는 개념이므로

[1] "data.table" "data.frame"

> ## 테이블과 프레임을 둘 다 가짐

>

> str(iris) ## [번외] DataSheetiris 변수

'data.frame':150 obs. of 5 variables:

$ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...

$ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...

$ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...

$ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...

$ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...

> head(iris)

  Sepal.Length Sepal.Width Petal.Length Petal.Width Species

1 5.1 3.5 1.4 0.2 setosa

2 4.9 3.0 1.4 0.2 setosa

3 4.7 3.2 1.3 0.2 setosa

4 4.6 3.1 1.5 0.2 setosa

5 5.0 3.6 1.4 0.2 setosa

6 5.4 3.9 1.7 0.4 setosa

> iris ## 데이터 프레임 상태의 iris -> 150개 모두 출력

  Sepal.Length Sepal.Width Petal.Length Petal.Width Species

1 5.1 3.5 1.4 0.2 setosa

2 4.9 3.0 1.4 0.2 setosa

3 4.7 3.2 1.3 0.2 setosa

4 4.6 3.1 1.5 0.2 setosa

5 5.0 3.6 1.4 0.2 setosa

6 5.4 3.9 1.7 0.4 setosa

(...)

145 6.7 3.3 5.7 2.5 virginica

146 6.7 3.0 5.2 2.3 virginica

147 6.3 2.5 5.0 1.9 virginica

148 6.5 3.0 5.2 2.0 virginica

149 6.2 3.4 5.4 2.3 virginica

150 5.9 3.0 5.1 1.8 virginica

> as.data.table(iris) ## 데이터 테이블로 변환한 iris -> 처음 5개와 끝 5개 출력

Sepal.Length Sepal.Width Petal.Length Petal.Width Species

1: 5.1 3.5 1.4 0.2 setosa

2: 4.9 3.0 1.4 0.2 setosa

3: 4.7 3.2 1.3 0.2 setosa

4: 4.6 3.1 1.5 0.2 setosa

5: 5.0 3.6 1.4 0.2 setosa

---

146: 6.7 3.0 5.2 2.3 virginica

147: 6.3 2.5 5.0 1.9 virginica

148: 6.5 3.0 5.2 2.0 virginica

149: 6.2 3.4 5.4 2.3 virginica

150: 5.9 3.0 5.1 1.8 virginica

>

> #데이터 테이블과 데이터 프레임의 차이점

> class(dataFrm$z) ## 데이터 프레임의 z변수: 팩터

[1] "character"

> class(dataTbl$z) ## 데이터 테이블의 z변수: 벡터(문자형)

[1] "character"

>

> #데이터 테이블의 행 선택 연산

> dataTbl[3,] ## 데이터 테이블의 3번째 행 전체 출력

   x y z

1: 3 6 B

> dataTbl[-(3:5),] ## 3~5번째 행 제외한 모든 값 출력

   x y z

1: 1 2 C

2: 2 4 C

3: 6 6 A

> dataTbl[x>3,] ## x3보다 큰 행을 선택하여 출력

   x y z

1: 4 2 B

2: 5 4 A

3: 6 6 A

> dataTbl[z=="A"] ## z"A"와 같은 행을 선택하여 출력 (반드시 == 사용)

   x y z

1: 5 4 A

2: 6 6 A

>

> #데이터 테이블의 열 선택 연산

> dataTbl[,y] ## 데이터 테이블의 변수 y 출력

[1] 2 4 6 2 4 6

> is.vector(dataTbl[,y]) ## 이 때, 출력하는 과정에서 벡터로 변환 -> is.vector() == TRUE

[1] TRUE

> dataTbl[,list(y)] ## list() 함수 이용하여 변환 없이 데이터 테이블 상태 그대로 출력

   y

1: 2

2: 4

3: 6

4: 2

5: 4

6: 6

> is.data.table(dataTbl[,list(y)])

[1] TRUE

> dataTbl[, list(y,z)]

   y z

1: 2 C

2: 4 C

3: 6 B

4: 2 B

5: 4 A

6: 6 A

>

> #데이터 테이블의 키 연산

> install.packages("UsingR")

> library(UsingR)

> str(reaction.time) ## DataSheet'reaction.time' 변수의 구조('str'ucture) 확인

'data.frame':60 obs. of 4 variables:

$ age : Factor w/ 2 levels "16-24","25+": 1 1 1 1 1 1 1 1 1 1 ...

$ gender : Factor w/ 2 levels "F","M": 1 2 2 1 2 2 2 1 1 2 ...

$ control: Factor w/ 2 levels "C","T": 2 2 2 2 2 1 2 2 2 1 ...

$ time : num 1.36 1.47 1.51 1.39 1.38 ...

> reaction.time.DT <- as.data.table(reaction.time)

## UsingR 패키지에서 다운받은 reaction.time 변수를 데이터 테이블로 변환

> setkey(reaction.time.DT, gender, control)

## setkey(데이터 테이블, 변수명1, 변수명2) 함수: 데이터 테이블 지정 + 색인 지정

> key(reaction.time.DT) ## 생성된 색인 확인, 자료의 실행속도 빠르게 하기 위하여 사용

[1] "gender" "control"

> reaction.time.DT[J("M","T")] ## 지정된 키를 사용하여 행에 접근할 때 J() 함수 이용

   age gender control time

1: 16-24 M T 1.467939

2: 16-24 M T 1.512036

3: 16-24 M T 1.384208

4: 16-24 M T 1.419043

5: 16-24 M T 1.292917

6: 16-24 M T 1.369171

7: 16-24 M T 1.352397

8: 25+ M T 1.345643

9: 25+ M T 1.341972

10: 25+ M T 1.502757

11: 25+ M T 1.463118

12: 25+ M T 1.520106

13: 25+ M T 1.444503

14: 25+ M T 1.517435

15: 25+ M T 1.536446

16: 25+ M T 1.444865

17: 25+ M T 1.527699

18: 25+ M T 1.466591

> ## 마지막 인수 중 "T": 실험군, "C": 대조군. 참고로 본 자료에선 운전 중 핸드폰 사용 여부에 따라 반응속도의 차이가

> ## 있는지 확인하기 위하여 운전 중 핸드폰을 사용한 그룹을 실험군 "T", 사용하지 않은 그룹을 대조군 "C"로 설정하였음