R복습_데이터구조 벡터(생성, 인덱싱,슬라이싱,이름지정,연산)

2024. 9. 25. 17:39R분석

데이터 구조

데이터 구조란 기본 자료형 변수와 달리 여러개의 값을 저장하는 저장공간을 말한다.
데이터구조는 데이터를 저장하는 방식이나 형식을 의미하며 데이터를 효율적으로 관리하고 분석하기 위한 필수적인 요소이다.
r에서 사용되는 데이터 구조는 다음과 같다.
 
 
R데이터 구조의 종류

  • 벡터(vector)
  • 행렬(matrix)
  • 배열(array)
  • 데이터 프레임(data frame)
  • 리스트(list)
  • 팩터(factor)

 

벡터

동일한 데이터 유형을 저장하는 1차원 데이터 구조이며 1차원 배열의 형태를 가진다. 벡터는 동일한 데이터의 유형만 저장할 수 있기때문에, 숫자형 벡터, 논리형벡터, 문자형벡터 등 벡터의 자료값은 항상 동일해아한다. r에서 가장 기본적이고 중요한 데이터 구조중 하나이며 데이터분석 작업의 기본단위로 사용된다.벡터의 요소로는 기본 자료형값이 들어갈 수있다.
 
 

백터 생성

#벡터 생성(vecter)
#벡터명 <- c()

v1 <- c(1,2,3,4);
#숫자형 벡터
print(v1);

print(class(v1)); #numeric출력(숫자형벡터)
print(typeof(v1)); #숫자는 기본적으로 실수타입

v2 <- c(1L,2L,3L);
print(typeof(v2)); #정수형 벡터
#변수 창에서 int로 표시

v3 <- c(TRUE, TRUE, FALSE);
print(v3);
print(typeof(v3)); #논리형 벡터

v4 <- c('a','b','c');
print(mode(v4)); #문자형 벡터
#벡터의 요소는 반드시 동일해야함

v5 <- c(1,2,TRUE,'HI');
print(v5);      
print(typeof(v5)); #character
#다른 타입으로 벡터를 만드는데 그 중 문자가있다면
#자동적으로 전부 문자타입으로 출력됨

v6 <- c(1,2,FALSE,TRUE);
print(v6);
print(typeof(v6)); #숫자(실수)형 벡터
#논리형과 숫자형이 벡터의 요소에 같이 있으면
#벡터의 요소는 숫자형 값이 된다.

백터를 생성할때는 벡터명 <- c()의 형태가 가장 기본이다. 벡터에 들어갈 요소들은 c()함수를 이용하여 벡터에 저장한다.
이때 c()함수안에 숫자만 넣게되면 숫자형 벡터, 문자만 넣게 되면 문자형 벡터가 된다. 만약 벡터에 다른 자료형으로 구성되어있는데 그 중 자료형중에 하나가 문자형이라면 벡터의 요소는 모두 문자형이 된다. 또한, 논리형의 경우 숫자로 치환이 가능하기때문에 숫자와 논리형값이 같이쓰이면 숫자형 벡터가 된다.

백터생성 옵션

일정한 간격으로 값 생성

#연속적인 숫자로 구성된 벡터생성
#벡터명 <- 시작값:종료값
v1 <- c(1:10)
v1 <- 1:10 #c함수 생략가능
print(v1) #1~10까지의 숫자 벡터생성

v2 <- c(1,3,5,7,10:20)
print(v2)
v3 <- c(1,2,3,10:15)
print(v3)

연속적인 숫자로 구성된 벡터를 생성해야할때 하나하나 값을 전부 적는것은  큰 시간낭비가될수있다.
이럴경우 벡터명<-  c(시작값:끝값)의 형태로 적어주면 자동적으로 벡터안에 연속된 값들이 삽입된다.  상황에따라 c함수를 생략하고 적어도 문제없이 값이 삽입된다.
또한 콤마로 값을 구분하여 다른 개별값들과도 함께 사용이 가능하다.


rep

#반복된 숫자로 이루어진 벡터생성
v6 <- rep(1,times=5)
print(v6) #1 6번 반복

v7 <- c(rep(1:5,times=3))
print(v7)


#숫자가 아닌값 반복하기
test <- rep('a',times=4)
print(test)

test1 <- rep('안녕',3) #times생략 가능 반복할 횟수만 적기
print(test1)

v8 <- rep(c(1,5,10),times=2)
print(v8)

v9 <- rep(c(1,5,10),each=2)
print(v9)

rep는 백터를 생성할때 특정값이 반복될수있도록한다. 벡터명 <- rep(값, times=반복할 횟수)의 형태로 적으며 상황에따라 times는 생략이 가능하다. 또한 값 하나만 반복가능한것이 아니라 연속된 숫자값이나 특정값들을 c()함수로 묶어전달하면 원하는 숫자만큼 연속된 숫자값이나 그룹으로 묶인 특정값들도 반복하여 출력할수있다.
rep의경우 숫자만 반복가능한것이 아니라 숫자이외의 값들도 반복하여 벡터안에 삽입이 가능하다.


seq

#일정한 간격의 숫자로 구성된 벡터생성
#seq(시작값, 종료값, 간격)
v3 <- seq(1,10,2)
print(v3)

v4 <- seq(5,15,3)
print(v4)

v5 <- c(seq(0.2,1.0,0.3))
print(v5)

seq는 일정한 간격으로 구성된 벡터를 생성할수있도록해준다. 형식은 벡터명<-seq(시작값, 끝값,간격)의 형태로 정의한다.  seq는 짝수만있는 벡터나 홀수만있는 벡터를 출력할때 자주사용되기도한다. 또한 숫자의 형태에 상관없이실수형도 seq사용이 가능하다.

 

벡터의 요소접근

 

인덱싱

#벡터의 특정요소 접근(인덱싱)
#벡터명[인덱스 번호]

v <- c('a','b','c','d','e')
print(v)
print(v[1])
print(v[2])
print(v[3])
print(v[4])
print(v[5])
print(v[6])#인덱스의 값을 넘어가면 결측값 반환


인덱싱은 벡터요소값에 개별로 접근하는방법이다.
형태는 벡터명[인덱스번호]를 사용한다.  만약 인덱스번호를 넘어가게되더라도 에러는나지않으며 결측값인 na가출력된다.

 

슬라이싱

#벡터의 여러요소에 접근(슬라이싱)
#벡터명[시작:종료]
print(v[1:3])
print(v[3:4])

print(v[seq(1,5,2)])
print(v[seq(1,5,3)])

슬라이싱은 벡터명[시작값 : 끝값]의 형태로 적으며 시작값부터 끝값까지 출력해서 보여주는 형식이다. 슬라이싱을 하게되면 벡터에서 더 작은 벡터를 가져오는 것과 같으므로, 슬라이싱으로 가져온 값들의 형태는 벡터이다.

 

특정값 제외

#벡터의 특정값 제외출력
print(v[-2])
print(v[-3])
print(v[-c(1:3)]) #인덱스 번호 중 3~5번까지 제외
print(v[-c(3:2)])

이번에는 특정값을 재외하고 모든 값을 가져오는 형태이다. 벡터명[-특정값]의형태로 적으며, 슬라이싱으로 값을 제외하고싶다면 벡터명[-c(시작값 : 특정값)]의 형태로 적는다.

 

 

벡터의 요소값에 이름설정

#벡터의 요소값에 이름설정
#names(벡터) <- c(이름1, 이름2,..)
score <- c(70,80,90)
names(score) <- c('짱구','유리','철수');
print(score)#이름과 요소들이 함께 출력
print(names(score)) #이름만 출력가능
print(score[1]) #인덱스 번호로 접근
print(score['짱구'])
print(score[c(1:2)])
print(score[c('짱구','유리')])
print(score[c('유리','철수')])
print(score[-2])
print(score[-'짱구']) #이름은 안됨

벡터에 입력된 요소에 개별적으로 이름을 부여하여 관리할 수 있다. 이름을 부여하는 방법은 names(벡터명) <- c(이름1, 이름2..)

의 형태로 적어 요소에 이름값을 전달한다. 이름을 부여하게 되면 벡터명['이름']의 형태로도 값에 접근이 가능하며, print(names(벡터명))을 입력하면 벡터에 부여된 이름값만 출력할 수 있다. 다만 이름으로 특정값을 제외하거나 슬라이싱할 수 없다.

 

 

벡터 값 수정

vec <- seq(10,100,10)
print(vec)

print(vec[1])
vec[1] <- 100
print(vec)
vec[2] <- 200
print(vec)

print(vec[2:4])
vec[2:4] <- c(200,300,400)
print(vec)

print(vec[seq(1,7,2)])
vec[seq(1,7,2)] <- c(1000,3000,500,700)
print(vec)

벡터의 값을 수정할때는 먼저 벡터의 요소에 접근해야한다. 그렇기때문에 인덱싱을 할때와 똑같이 벡터명[인덱스 번호]<-수정할 값

의 형태로 입력하게 되면  해당 인덱스번호 자리에 있던 요소값이 수정값으로 대체되어 수정된다. 

만약 수정할 값이 여러개라면 슬라이싱의 형태로 값을 수정해야하며, 수정할때는 sep를 사용하여 수정할 수 도 있다.

벡터명[seq(시작값 : 끝값 : 간격)]의 형태로 적게되면 해당 간격에 있는 요소값만 수정할 수 있다.

 

 

벡터와 연산자 사용

 

벡터와 산술연산자

#벡터와 산술연산자
v1 <- c(1,4,5,7,9)
print(v1)

print(v1+10) #벡터의 각 요소마다 10이 더해짐
print(v1+20)
print(v1+30)
print(v1*2) #다른 연산들도 가능
print(v1-3)


#벡터끼리의 산술연산
v2 <- seq(1,15,3)
print(v2)

print(v1+v2)#백터간 대응되는 위치에 있는 요소끼리연산
print(v1*v2)
print(v2+(v1*2))#연산자 자유롭게 사용가능

벡터에서는 산술연산이 가능하다. 벡터명+10을 하게되면 벡터의 요소별로 +10이 되는 형식이다. 이렇게 벡터와 값끼리의 연산이외에도 벡터끼리도 산술연산이 가능한데, 길이가 같은 벡터끼리 산술연산을 하게되면 각각의 요소 위치가 같은 값끼리 산술연산이 되어 출력된다.

#벡터의 길이가 같지 않은 벡터끼리의 연산
v3 <- c(1,2,3)
print(v1+v3)
#서로배수관계에 있지않다는 오류발생
#벡터의길이가 같지 않음

cat('v1의 벡터길이: ',length(v1))
cat('v2의 벡터길이: ',length(v3))
#길이가 다른경우 서로 배수관계에 있다면 계산이 가능함
#(2,4), (3,9)개 등등..

v4 <- 1:6
print(v4)

print(v3+v4)
#길이가 다름에도 불구하고 오류나지않음
cat('v3의 벡터길이: ', length(v3))
cat('v4의 벡터길이: ',length(v4))
#각각 위치가 맞는 벡터의 요소끼리 계산한다음
#길이가 더 짧은 벡터가 다시힌번 순서가 돌아가며 배수끼리게싼
#재사용법칙!

만약 벡터끼리 산술연산시에 벡터끼리의 길이가 맞지 않는다면 계산이 되지 않으며, 배수관계에 있지 않는다는 에러가 발생한다. 하지만 길이가 다르더라도 벡터끼리의 길이가 배수관계(2,4)에 있다면 길이가 더 짧은 쪽이 한번데 길이가 긴 벡터에 맞춰 값이 할당되는 재사용의 법칙으로 인해 에러없이 계산된다.

 

 

벡터에서 사용가능한 함수

#벡터에서 사용가능한 함수
v <- c(1,3,5,7,9)
cat('벡터의 길이: ', length(v))
cat('벡터 요소의 합: ',sum(v))
cat('벡터 요소의 평균: ',mean(v))
cat('벡터의 최대값: ',max(v))
cat('벡터의 최소값: ',min(v))
cat('벡터의 중간값: ',median(v))
cat('벡터 요소의 범위: ', range(v)) #최소값, 최대값반환

 

 

벡터와 관계연산자

#벡터와 관계연산자
v <- 1:9
print(v)


print(v>5) #벡터의 요소하나하나가 5보다 큰지 물어보는것
#조건에맞는 값들은 TRUE로 출력되고 아닌 값들은 FALSE로출력

print(v[v>5])#벡터의 요소중에 참값인 애들만 뽑앗 
#새로운 벡터를 만든것
#v[조건식] : 필터링이라고 부름
#조건식 : 결과가 TRUE,FALSE논리형으로 나오는 식

condi <- (v>5 & v<8) #벡터의 요소중 5보다 크고 8보다 작은 것드이 조건
print(condi)
print(v[condi]) #조건에 맞는애들만 따로 빼서 벡터로 만들어줌

condi <- !(v<=3 | v>=8)
print(condi)
print(v[condi])

벡터에서는 관계연산자 사용이가능하다. 벡터>5라고 적게되면 해당 벡터의 요소중에 5보다 큰값은 TRUE로, 아닌값들은 FALSE로 반환되어 출력한다. 만약 논리형값 말고 실제 값만 관계연산자의 조건에 해당하는 값만 보고싶다면 print(벡터명[벡터명>5])라는 형태로 적는다. [] 대괄호안에 들어가는것은 조건문이 되고, 그 조건문에 해당하는 값대로 새로운 벡터를 형성해서 출력해주는것과 동일한 원리이다.

 

 

벡터 활용 실습코드

 

실습코드 1

#<실습1>
#1)10,11,13,15,16 5개의 값을 가지는 벡터 생성
v <- c(10:16)
print(v)
#2)15~25까지의 값을 가지는 벡터 생성
v1 <- c(15:25)
print(v1)
#3) 20~30까지의 숫자 중 짝수만을 가지는 벡터 생성
v2 <- seq(20,30,1)
print(v2)
condi <- (v2%%2==0)
print(v2[condi])
#4)20개의 TURE라는 요소를 가지는 벡터 생성
v3 <- rep(TRUE,times=20)
print(v3)
print(typeof(v3))

(1,2번째의 코드는 간단하니 설명패스)첫번째 코드의 3번째의 경우에는 %%나머지연산자를 통해 2로 나눴을때 나머지가 0이라면 무조건 짝수이므로 조건에 이를 조건에 넣어 값을 출력하도록 했으며 4번의 경우 TRUE값이 20번 들어가는 벡터의 경우, rep을 이용하여 만들수도 있으며, 양수를 넣고 음수보다 큰수를 보여달라는 관계연산자를 통해 만들수도있다. 

 

 

실습코드 2

#<실습2>
#1)100에서 150까지 저장된 벡터 생성
v4 <- 100:150
print(v4)

#2)위의 벡터에서 10번째 값 출력
print(v4[10])

#3) 위의 벡터에서 3~12번째 값 출력
print(v4[3:12])


#4) 위의 벡터에서 맨끝에서 10개의 값들만 제외하고 출력
print(length(v4))
print(v4[-c(41:51)])

#5)위의 벡터에서 홀수값들 만 출력
print(v4[seq(1,51,3)])
print(v4[v4%%2==1])

#6) 앞에서부터 20개의 값을 1부터 20이라는 값으로 수정하고 출력
v4[1:20] <- 20
print(v4)

 

4번의 경우 벡터요소의 길이를 반환해주는 length의 함수를 사용하여 벡터의 길이를 알아낸 다음, 거기서부터 10개를 뺀 값인 인덱스번호를 적어 출력되지 않도록 했다.

 

 

 

실습코드 3

#<실습3>
#짱구, 철수, 맹구, 훈이, 유리 5명의 학생의 점수
# 각각 60,95,55,70,85점
#학생의 점수를 요소로 가진 벡터 생성
#벡터의 요소마다 학생의 이름으로 요소명 지정하고 출력

student <- c(60,95,55,70,85)
print(student)
names(student) <- c('짱구','철수','맹구','훈이','유리')
print(names(student))
print(student)


#학생의 인원수 출력
cat('학생 인원수: ',length(student),'명')

#학생들의 총점 출력'
cat('학생 총점: ',sum(student),'점')

#학생들의 평균 점수 출력
cat('학생들 평균점수: ',mean(student),'점')

# 5) 학생들의 중간점수 출력
cat('학생들의 중간점수', median(student),'점')

# 6) 5명 학생의 점수 중 최대값, 최소값 출력
cat('학생점수 최대, 최소값: ',range(student))

names을 통해 점수에 각각 학생들의 이름으로 이름값을 지정하였고 cat함수를 사용하여 문제에서 원하는 값이 한문장으로 깔끔하게 출력되도록 했다.



학습일기


데이터의 구조 중 가장 기본이되는 벡터에 대해 학습했다. 크게 어려운점은없었으나 인덱싱이나 슬라이싱할때 여러값을 출력할경우 c()로묶어주어야한다는걸 좀 자주 잊는것같다.  이 부분 주의해야할것같다..
그외에 크게 어려운점은없었지만 벡터는 행열이나 배열부분에서 출력방식에따라 다시등장하는 만큼 정말 기본과 토대가 되기때문에 혼동되는점없이 단단하게 기초를 잘 잡아야겠다고 느꼈다..!