-
R과 데이터프레임 (1)R 이모저모 2019. 3. 10. 22:31
R에서의 데이터프레임 기초와 활용방법
R에서 데이터프레임은 직관적이며 dplyr등 tidyverse 패키지들로 다루기 쉽기 때문에 여러 패키지가 Input, 혹은 Output으로 활용하는 데이터 타입입니다. 이 포스팅에서는 데이터프레임이 어떤 역할을 하고 어떻게 생성하는지에 대한 기초를 알아보고자 합니다.
1. R 데이터프레임의 정의
데이터프레임은 R에 있는 2차원 데이터 형식의 하나로, 데이터프레임에 대해서 설명하는 말들은 여러 곳에서 찾아볼 수 있지만, R Documentation에서는 간단히 A data frame is a list of variables of the same number of rows with unique row names, given class "data.frame" 으로 서술하고 있습니다. 언뜻 보기에 추상적인 말들은 R내에서 직접 코드를 실행해보면 쉽게 확인해볼 수 있는데요.
예를 들어 'list of variables' 부분은 데이터 프레임의 칼럼을 list 타입처럼 $ operator로 호출할 수 있는 것을 볼 수 있습니다.또한 ...of same number of rows with unique row names는 모든 변수들(Column)이 빈 값이 없이 같은 개수의 행을 가지고, 각각의 행은 고유의 이름을 가짐을 의미합니다. 여기서 주의할 점은 빈 값이 없다는 얘기는 NULL값이 없다는 뜻이고 NA는 존재할 수 있습니다. 이는 데이터프레임 생성 시 NULL값을 입력해보면 알 수 있는데, 밑에 그림처럼 NULL을 넣으면 자동으로 다른 값으로 채워넣고 그마저도 없다면 에러가 뜨는 모습을 볼 수 있습니다.
데이터프레임은 위 코드들에서 보다시피 data.frame함수로 직접 정의하거나 있는 행렬(Matrix)이나 list를 as.data.frame 같은 함수로 치환해 줄 수도 있습니다. data.frame으로 직접 정의할 경우 'a = 1:10'이라고 정의한 부분에서 a가 변수이름, 1:10이 해당 변수의 값이 됩니다.
2. R 데이터프레임의 Indexing
R은 파이썬의 판다스 데이터프레임에 비해서 좀 더 직관적인 인덱싱 방법을 사용하고 있습니다. 행렬과 같은 일반적인 2차원 데이터에서 사용하는 인덱싱으로 간편하게 불러올 수 있습니다. 예를 들어 df라는 data.frame 객체의 첫번째 행과 모든 열을 가져오고 싶다면 df[1,]를 사용하면 됩니다. 반대로 첫번째 열과 모든 행을 가져오려면 df[,1]을 사용하면 됩니다.
또 하나의 방법은 대괄호 안에 숫자 대신 이름으로 호출해오는 방법입니다. 보통 행의 이름은 1부터 숫자로 지정되어 있어 큰 의미는 없지만, 열을 가져올 때는 유용하게 사용할 수 있습니다. 예를 들어 df의 a행을 가져오고 싶다면 df[,'a']로 호출하는 것입니다. 이는 언뜻 보기엔 별 의미 없어 보이지만 특정 이름을 가진 변수만 가져오고 싶을 경우 매우 유용하게 사용할 수 있습니다.
이러한 indexing 특성을 활용하면 특정 값이 어디에 위치하는지를 찾아낼 수 있는데, which함수가 벡터 혹은 array를 받고 해당 조건에 맞는 자리를 찾아주기 때문입니다. 예를들어 데이터프레임의 변수 a가 1인 행을 호출하고 싶다면 아래와 같이 진행하면 됩니다.
첫 예제는 df의 a가 1인 경우가 하나뿐이라서 하나의 행을 출력하고, 두번째에서는 b 가 d인 경우가 모두 출력됨을 알 수 있습니다.
*다만 이 경우 주의할 점은 which는 어디까지나 해당 조건에 부합하는 숫자를 출력해주는 함수일 뿐이라는 것입니다. 예를들어 which(df$b == 'd')라는 함수를 콤마 앞이 아닌 뒤에 넣게 되면 해당 숫자를 데이터프레임의 행이 아닌 열에 집어넣어 원치 않는 인덱싱을 불러오게 됩니다. arr.ind(array indices) 옵션을 활용하는 방법은 추후 다루겠습니다.
3. R 데이터프레임의 Attributes
여타 R내의 오브젝트들이 그러하듯, 데이터프레임도 attributes()함수로 안의 구성요소를 확인해 볼 수 있습니다. 이 함수의 출력값은 list 형태로 저장되며 names, class, row.names 3개의 요소를 가지고 있습니다
names : colnames 혹은 names 함수로 호출 가능한 데이터프레임의 칼럼 이름(= 변수 이름)입니다
class : 이 객체의 class입니다. 보통 data.frame 하나를 가지지만 tibble 등 복수의 class를 가질 때도 있습니다.
row.names : 앞서 언급된 행의 고유명으로 특별히 지정하지 않았다면 1부터 행의 개수만큼 숫자로 지정되있습니다.
보통 이 값들을 건드릴 이유는 없지만, 칼럼이나 행의 이름을 수정해야 할 경우 rownames(df) = c('a','b') colnames(df) = c('a','b') 같은 식으로 조정할 수 있습니다. 이는 일반적인 R 함수의 경우 함수의 결과를 타겟으로 값을 지정할 수 없는데에 비해 예외적인 경우라고 할 수 있겠습니다.
4. 그 외 이모저모
4.1 순서 정렬
R에서는 order라는 함수로 벡터의 순서 변경을 가능하게 합니다. 예를 들어 1:10(1,2,3...,10)인 벡터를 역순으로 배열하고 싶다면 order(1:10, decreasing= T)를 사용하면 됩니다. 이를 응용하면 데이터프레임의 순서도 어렵지 않게 정렬할 수 있습니다. 예를 들어 a를 기준으로 증감하는 순으로 정렬하고 싶다면 위의 인덱싱에서 사용한 방식 그대로df[order(df$a,decreasing = T),] 라고 입력하면 됩니다. dplyr에서는 arrange라는 함수로 보다 쉽게 정렬할 수 있도록 설정해놨지만 이 방법은 2편에서 dplyr에 대해 자세히 설명하면서 쓰도록 하겠습니다.4. 2 데이터 추가데이터를 어디선가 읽어와서 R환경에 추가하고 나서 분석을 하다보니 R 환경 내에서만 데이터에 변수를 추가한다던가 행을 추가하고 싶을 수 있습니다.먼저 열을 추가하는 방법을 보자면 cbind() 함수를 사용하거나 df$c = 1:10 같은 식으로 추가하는 방법이 있습니다
그림 추가 편의상 head함수를 활용해 5개만 보이게 지정했습니다
cbind는 앞에 기존 객체를 설정한 다음 추가하고자 하는 데이터를 입력하는 형식을 취합니다. 이때 입력하는 데이터는 data.frame으로 지정하거나 그냥 벡터를 집어넣는 등 여러가지 방법으로 정의해줄 수 있습니다. 주의할 점은 cbind를 통해 나오는 객체는 df라는 기존 객체와 별도의 객체이니 추가를 해주고 싶다면 df = cbind(df,c = 1:10) 처럼 직접 할당해주어야 한다는 것입니다.
두번째 방법은 직접 값을 지정해서 넣어주는 것으로 존재하지 않는 c라는 열을 df$c로 호출한 다음 '= 1:10'으로 값을 지정해주면 됩니다. 단, 아까 정의에서 언급한 것 처럼 모든 행과 열이 값을 가져야하기 때문에 입력하는 길이는 기존의 열의 길이(= 행의 갯수)와 같아야합니다.
행의 추가는 열보다 보다 엄격한 편으로, 이는 data.frame에 팩터 타입의 변수가 있을 경우 기존에 정의된 팩터 레벨 이외의 것을 받아들이지 않기 때문입니다. 저희가 맨 처음 정의한 df의 b라는 변수에는 a,b,c,d라는 4개의 문자밖에 없으므로 이 변수를 일반 문자열 변수로 받아들이도록 설정하지 않았다면 시스템은 a,b,c,d이외의 다른 문자가 들어오는 것을 막게 됩니다.
위 그림에서 보다시피 a에 5, b에 7의 값이 들어가는 행을 할당하였더니 팩터 레벨(팩터의 고유 가지 수 = a,b,c,d)과 맞지 않아 NA값이 생성되었습니다. 그에 반해 두 번째 스크립트는 b에 a라는 이미 있는 값을 할당하여서 올바르게 작동하는 모습을 볼 수 있습니다.
열 추가와 마찬가지로 행도 df[11,] = data.frame(a = 5,b = 'a') 과 같이 추가해 줄 수 있습니다. 다만 이 경우에도 위 rbind와 같이 팩터 변수에 대해서는 주의를 할 필요가 있습니다.
4. 3 요약
특정 데이터프레임의 개요는 두 가지 함수로 볼 수 있는데 첫째는 str, 둘째는 summary입니다. summary는 변수들의 통계치를 나열해주며 str은 객체의 클래스, 행과 열의 수, 각 열의 타입 및 값 등을 보여주게 됩니다. 주로 분석의 맨 처음 단계에 데이터를 불러온 후 누락값은 없는지, 분포가 어떻게 되는지 등을 확인하기 위하여 가장 먼저 살펴보게 됩니다.
5. 마치며
이번 포스팅에서는 R 데이터프레임이 무엇이고 어떻게 생성하는지, 값들은 어떻게 불러내고 추가할 수 있는지 등을 살펴보았습니다.
다음 포스팅에서는 dplyr라는 유명한 패키지를 사용하여 데이터프레임을 보다 빠르고 쉽게 조작하는 법, apply기반 함수를 통해 열 간 전처리 작업을 병렬처리하게 되는 법 등 R을 사용하면서 짧게나마 느낀 팁에 대해서 써보도록 하겠습니다.
[ 컨텐츠 코드 ]'R 이모저모' 카테고리의 다른 글
R과 병렬처리 (4) 2019.04.03 알고리즘 소개 : XGBoost (0) 2019.03.30 R과 데이터프레임(3) (0) 2019.03.24 각양각색의 R 질문들과 풀이 (0) 2019.03.21 R과 데이터프레임(2) : dplyr (0) 2019.03.14