= c("David", "Brownie")
a = 100
b = matrix(1:4, nrow = 2)
c = list(u = a, v = b, w = c)
mylist mylist
$u
[1] "David" "Brownie"
$v
[1] 100
$w
[,1] [,2]
[1,] 1 3
[2,] 2 4
Acknowledgement: 본 절의 구성에는 다음 교재를 발췌하였다.
데이터 프레임 (data.frame) : 길이가 동일한 수치/문자열/논리 벡터들을 열별로 합쳐놓은 자료형. 지난 세션까지는 벡터 자료형과 행렬 자료형만 주로 다루었다. 벡터와 행렬 모두 한 객체에 동일한 유형 (수치형이면 수치형, 문자열이면 문자열)만 저장할 수 있다. 그러나 보통의 테이블 자료(tabular data)는 열(필드)마다 수치/문자열/논리 유형이 다른 복합 테이블이므로, R의 행렬 자료형은 테이블 자료를 담기에 적절하지 않고, 데이터 프레임으로 담아낼 수 있다.
리스트 (list) : 리스트는 여러 객체들의 단순 모음이다. 서로 다른 길이의 벡터, 행렬, 문자열, 혹은 다른 리스트도 모아놓을 수 있다.
= c("David", "Brownie")
a = 100
b = matrix(1:4, nrow = 2)
c = list(u = a, v = b, w = c)
mylist mylist
$u
[1] "David" "Brownie"
$v
[1] 100
$w
[,1] [,2]
[1,] 1 3
[2,] 2 4
= list( u = c("David", "Brownie"), v = 100, w = matrix(1:4, nrow = 2) )
mylist $u mylist
[1] "David" "Brownie"
$w mylist
[,1] [,2]
[1,] 1 3
[2,] 2 4
1]] mylist[[
[1] "David" "Brownie"
2]] mylist[[
[1] 100
3]] mylist[[
[,1] [,2]
[1,] 1 3
[2,] 2 4
$w[2, 1] mylist
[1] 2
= matrix(1:4, nrow = 2, byrow = T)
mat qr(mat)
$qr
[,1] [,2]
[1,] -3.1622777 -4.4271887
[2,] 0.9486833 -0.6324555
$rank
[1] 2
$qraux
[1] 1.3162278 0.6324555
$pivot
[1] 1 2
attr(,"class")
[1] "qr"
qr(mat)$qr
[,1] [,2]
[1,] -3.1622777 -4.4271887
[2,] 0.9486833 -0.6324555
= qr(mat)
Q $qr Q
[,1] [,2]
[1,] -3.1622777 -4.4271887
[2,] 0.9486833 -0.6324555
= c("David", "Brownie", "John")
name = c(20, 10, 23)
age = c(10, 9, 10)
score = data.frame(name, age, score)
mydata mydata
name age score
1 David 20 10
2 Brownie 10 9
3 John 23 10
= data.frame(name = c("David", "Brownie", "John"),
mydata age = c(20, 10, 23), score = c(10, 9, 10))
1] mydata[ ,
[1] "David" "Brownie" "John"
1, ] mydata[
name age score
1 David 20 10
$name mydata
[1] "David" "Brownie" "John"
getwd()
[1] "/Users/cyg/Dropbox/Documents/Teaching/2024g-longitudinal/lecNote_longitudinal"
= data.frame(name = c("David", "Brownie", "John"),
mydata age = c(20, 10, 23), score = c(10, 9, 10))
write.csv(mydata, '/Users/cyg/Dropbox/Documents/Teaching/2024g-longitudinal/lecNote_longitudinal/CS_mydata.csv')
"name" "age" "score"
"1" "David" 20 10
"2" "Brownie" 10 9
"3" "John" 23 10
write.table(mydata, '(경로)/CS_mydata_nonames.txt', row.names=FALSE, col.names=TRUE)
"David" 20 10
"Brownie" 10 9
"John" 23 10
X = read.csv("(경로)/CS_mydata.csv", header=TRUE)
X
name age score
1 David 20 10
2 Brownie 10 9
3 John 23 10
다음과 같은 데이터 프레임 scoretable이 있다.
> scoretable
name math english physics
1 Stark 52 45 72
2 Stacy 22 84 73
3 John 59 31 90
4 Brownie 84 29 75
5 Sam 71 73 30
6 Sherry 56 19 82
e:\CS\scoretablenew.csv
로 저장코자 한다. 이를 위한 코드를 작성하여라.(Hint : for 함수를 이용해서 열별/행별로 평균 및 합을 계산하는 것이 가장 기본적이나, 이제부터는 함수 rowSums(), rowMeans(), colSums(), colMeans()를 이용하자. 네 함수 모두 input 인자는 행렬이다. 행렬 하나를 만든 다음에 위 함수들을 테스트해 보면 금방 그 뜻과 사용법을 알 것이다.)
stu.mean = rowMeans( scoretable[ ,-1] ) # 1열에는 문자형 자료가 있으므로 1열 제거
stu.sum = rowSums( scoretable[ ,-1] )
scoretable.new = data.frame(scoretable, mean = stu.mean, sum = stu.sum)
write.csv(scoretable.new, "(경로)/scoretablenew.csv", row.names=FALSE, col.names=TRUE)
subject.mean = colMeans( scoretable[ ,-1] )
subject.sum = colSums( scoretable[ ,-1] )
scoretable.list = list(scoretable.new, subject.mean, subject.sum)
물론 for (i in 1:5)… 로 시작하는 구문을 이용하여 인덱스 하나하나에 대해 8보다 큰지 if문을 통해 물어보고 맞으면 그 index를 …… 하는 방법으로 위의 문제에 대처할 수는 있다. R에서는, 머리를 좀 굴린다는 전제 하에 매우 간단하게 할 수 있다.
= c(7, 2, 30, 6, 9)
x c(4, 3, 3, 5, 1, 1) ] x[
[1] 6 30 30 9 7 7
= c(7, 2, 30, 6, 9)
x c(T, F, T, T, F) ] x[
[1] 7 30 6
# x[ c(TRUE, FALSE, TRUE, TRUE, FALSE) ] 라 쓰는 것과 똑같다.
c(T, F, T, T, F, T, F) ] x[
[1] 7 30 6 NA
= 4 ; x = c(7, 2, 30, 6, 9)
a > 8 a
[1] FALSE
> 8 x
[1] FALSE FALSE TRUE FALSE TRUE
which( c(F, F, T, F, T) )
[1] 3 5
which( x > 8 )
[1] 3 5
두 명령어가 왜 같은 답을 주는가?
②를 해결하여 보자. 아래 명령어들이 사실 모두 같은 말을 하고 있다는 것이 포인트. 반복적인 실험을 위해 원본 x로부터 사본 y를 복사해서 쓰자.
= c(7, 2, 30, 6, 9)
x = x
y c(3, 5) ] = 0
y[ y
[1] 7 2 0 6 0
= x
y which(y > 8) ] = 0
y[ y
[1] 7 2 0 6 0
= x
y c(F, F, T, F, T) ] = 0
y[ y
[1] 7 2 0 6 0
= x
y > 8 ] = 0
y[ y y
[1] 7 2 0 6 0
= c(10, 15, 1, 5, 12) ; x = c(7, 2, 30, 6, 9)
a = a ; y = x b
which( y^2 < 40 )
[1] 2 4
^2 < 40 ] = 0
y[ y y
[1] 7 0 30 0 9
= x
y <= 10 ] = 0
y[ b y
[1] 0 2 0 0 9
which( (b >= 5) & (b <= 15) )
[1] 1 2 4 5
= c(7, 2, 30, 6, 9)
x order(x)
[1] 2 4 1 5 3
rank(x)
[1] 3 1 5 2 4
c(2, 4, 1, 5, 3) ] x[
[1] 2 6 7 9 30
order(x) ] x[
[1] 2 6 7 9 30
= c(7, 2, 30, 6, 9)
x order(x, decreasing=TRUE)
[1] 3 5 1 4 2
order(x, decreasing=TRUE)] x[
[1] 30 9 7 6 2
= c("A", "B", "C", "D", "E")
name = c(69, 19, 74, 53, 90)
math = c(28, 85, 74, 57, 91)
eng = data.frame(name, math, eng)
data
# 수학이 50점 이상인 사람만 출력
$math >= 50) , ] data[ (data
name math eng
1 A 69 28
3 C 74 74
4 D 53 57
5 E 90 91
# 이름순 나열
order(data$name), ] data[
name math eng
1 A 69 28
2 B 19 85
3 C 74 74
4 D 53 57
5 E 90 91
# 총점을 계산하여 총점순으로 나열
= data$math + data$eng
total = data.frame(data, total)
data = order(total, decreasing=TRUE)
order.total data[ order.total , ]
name math eng total
5 E 90 91 181
3 C 74 74 148
4 D 53 57 110
2 B 19 85 104
1 A 69 28 97
# 수학이 50점 이하인 사람을 50점으로 고정
$math[ (data[ ,2] <= 50) ] = 50 data
Remark. NA나 NULL은 문자형 상수가 아니다. 예를 들면, a = “NA”라고 입력하는 것과 a = NA라고 입력하는 것은 전혀 다르다.
= c("A", "B", "C", "D", "E")
name = c(69, NA, 74, 53, 90)
math = c(28, 85, 74, 57, NA)
eng = c(28, 85, 74, 57, NULL)
eng2 = data.frame(name, math, eng)
data # data2 = data.frame(name, math, eng2) # 에러 발생
is.na(data$math)
[1] FALSE TRUE FALSE FALSE FALSE
$math == NA # c(NA, NA, NA, NA, NA) 출력될 것임 - 옳은 문법이 아님 data
[1] NA NA NA NA NA
$name[ is.na(data$math) ] data
[1] "B"
$math[ is.na(data$math) ] = 0
data$eng[ is.na(data$eng) ] = 0
data# data[ is.na(data) ] = 0 해도 됨
R은 벡터/행렬 단위의 연산이 가능, 길이가 다른 두 벡터의 연산에서는 만나면 짧은 벡터가 알아서 반복되며 긴 벡터와 길이를 강제로 맞춤
기본적인 이항 연산자
*
, /, %%(mod)
, ^, %*%
기본적인 수치 연산 함수 (numeric 형 벡터/행렬에서만 가능)
자료형별 객체생성법
개체 성분들의 유형 : character, logical, numeric, complex 등
자료형별 객체 접근법
외부 csv 파일로의 입출력 : read.csv(file, header=?), write.csv(data, file, row.names=?, col.names=?)
= c(7, 2, 30, 6, 9) ; X = matrix(1:16, ncol=4)
a which(a >= 2)
[1] 1 2 3 4 5
>= 1) & (a <= 4) ] = NA
a[ (a %% 2) == 1 ] = 0
X[ (X upper.tri(X) ] = 1000
X[ row(X) > col(X) ] = 5000 X[
= c(7, 2, 30, 6, 9)
x order(x)
[1] 2 4 1 5 3
order(x, decreasing=TRUE)
[1] 3 5 1 4 2
rank(x)
[1] 3 1 5 2 4
order(x) ] x[
[1] 2 6 7 9 30
= c("DH", "YE", "SH", "YG", "JH", "YS", "HS")
name = c(69, 19, 74, 53, 90, 14, 67)
math = c(28, 85, 74, 57, 91, 27, 14)
eng = data.frame(name, math, eng)
data
2] >= 50), ] # 수학이 50점 이상인 사람만 출력 data[ (data[ ,
name math eng
1 DH 69 28
3 SH 74 74
4 YG 53 57
5 JH 90 91
7 HS 67 14
order(data[ ,1]), ] # 이름순 나열 data[
name math eng
1 DH 69 28
7 HS 67 14
5 JH 90 91
3 SH 74 74
2 YE 19 85
4 YG 53 57
6 YS 14 27
# 총점을 계산하여 총점순으로 나열
= as.vector(data[ ,2]) + as.vector(data[ ,3])
total = data.frame(data, total)
data = order(total, decreasing=TRUE)
order.total data[ order.total , ]
name math eng total
5 JH 90 91 181
3 SH 74 74 148
4 YG 53 57 110
2 YE 19 85 104
1 DH 69 28 97
7 HS 67 14 81
6 YS 14 27 41
= function(x) return( sum(x^2) )
mynorm = function(x) return( c(max(x), min(x)) )
maxmin = matrix(1:16, 4, 4)
X apply(X, 1, mean)
[1] 7 8 9 10
apply(X, 2, mynorm)
[1] 30 174 446 846