a = c("David", "Brownie")
b = 100
c = matrix(1:4, nrow = 2)
mylist = list(u = a, v = b, w = c)
mylist$u
[1] "David" "Brownie"
$v
[1] 100
$w
[,1] [,2]
[1,] 1 3
[2,] 2 4
Acknowledgement: 본 절의 구성에는 다음 교재를 발췌하였다.
데이터 프레임 (data.frame) : 길이가 동일한 수치/문자열/논리 벡터들을 열별로 합쳐놓은 자료형. 지난 세션까지는 벡터 자료형과 행렬 자료형만 주로 다루었다. 벡터와 행렬 모두 한 객체에 동일한 유형 (수치형이면 수치형, 문자열이면 문자열)만 저장할 수 있다. 그러나 보통의 테이블 자료(tabular data)는 열(필드)마다 수치/문자열/논리 유형이 다른 복합 테이블이므로, R의 행렬 자료형은 테이블 자료를 담기에 적절하지 않고, 데이터 프레임으로 담아낼 수 있다.
리스트 (list) : 리스트는 여러 객체들의 단순 모음이다. 서로 다른 길이의 벡터, 행렬, 문자열, 혹은 다른 리스트도 모아놓을 수 있다.
a = c("David", "Brownie")
b = 100
c = matrix(1:4, nrow = 2)
mylist = list(u = a, v = b, w = c)
mylist$u
[1] "David" "Brownie"
$v
[1] 100
$w
[,1] [,2]
[1,] 1 3
[2,] 2 4
mylist = list( u = c("David", "Brownie"), v = 100, w = matrix(1:4, nrow = 2) )
mylist$u[1] "David" "Brownie"
mylist$w [,1] [,2]
[1,] 1 3
[2,] 2 4
mylist[[1]][1] "David" "Brownie"
mylist[[2]][1] 100
mylist[[3]] [,1] [,2]
[1,] 1 3
[2,] 2 4
mylist$w[2, 1][1] 2
mat = matrix(1:4, nrow = 2, byrow = T)
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
Q = qr(mat)
Q$qr [,1] [,2]
[1,] -3.1622777 -4.4271887
[2,] 0.9486833 -0.6324555
name = c("David", "Brownie", "John")
age = c(20, 10, 23)
score = c(10, 9, 10)
mydata = data.frame(name, age, score)
mydata name age score
1 David 20 10
2 Brownie 10 9
3 John 23 10
mydata = data.frame(name = c("David", "Brownie", "John"),
age = c(20, 10, 23), score = c(10, 9, 10))
mydata[ ,1][1] "David" "Brownie" "John"
mydata[1, ] name age score
1 David 20 10
mydata$name[1] "David" "Brownie" "John"
getwd()[1] "/Users/cyg/Dropbox/Documents/Teaching/2025g-SEM/lecNote_SEM"
mydata = data.frame(name = c("David", "Brownie", "John"),
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에서는, 머리를 좀 굴린다는 전제 하에 매우 간단하게 할 수 있다.
x = c(7, 2, 30, 6, 9)
x[ c(4, 3, 3, 5, 1, 1) ][1] 6 30 30 9 7 7
x = c(7, 2, 30, 6, 9)
x[ c(T, F, T, T, F) ] [1] 7 30 6
# x[ c(TRUE, FALSE, TRUE, TRUE, FALSE) ] 라 쓰는 것과 똑같다.
x[ c(T, F, T, T, F, T, F) ][1] 7 30 6 NA
a = 4 ; x = c(7, 2, 30, 6, 9)
a > 8[1] FALSE
x > 8[1] FALSE FALSE TRUE FALSE TRUE
which( c(F, F, T, F, T) )[1] 3 5
which( x > 8 )[1] 3 5
두 명령어가 왜 같은 답을 주는가?
②를 해결하여 보자. 아래 명령어들이 사실 모두 같은 말을 하고 있다는 것이 포인트. 반복적인 실험을 위해 원본 x로부터 사본 y를 복사해서 쓰자.
x = c(7, 2, 30, 6, 9)
y = x
y[ c(3, 5) ] = 0
y[1] 7 2 0 6 0
y = x
y[ which(y > 8) ] = 0
y[1] 7 2 0 6 0
y = x
y[ c(F, F, T, F, T) ] = 0
y[1] 7 2 0 6 0
y = x
y[ y > 8 ] = 0
y[1] 7 2 0 6 0
a = c(10, 15, 1, 5, 12) ; x = c(7, 2, 30, 6, 9)
b = a ; y = xwhich( y^2 < 40 )[1] 2 4
y[ y^2 < 40 ] = 0
y[1] 7 0 30 0 9
y = x
y[ b <= 10 ] = 0
y[1] 0 2 0 0 9
which( (b >= 5) & (b <= 15) )[1] 1 2 4 5
x = c(7, 2, 30, 6, 9)
order(x)[1] 2 4 1 5 3
rank(x)[1] 3 1 5 2 4
x[ c(2, 4, 1, 5, 3) ][1] 2 6 7 9 30
x[ order(x) ][1] 2 6 7 9 30
x = c(7, 2, 30, 6, 9)
order(x, decreasing=TRUE)[1] 3 5 1 4 2
x[order(x, decreasing=TRUE)][1] 30 9 7 6 2
name = c("A", "B", "C", "D", "E")
math = c(69, 19, 74, 53, 90)
eng = c(28, 85, 74, 57, 91)
data = data.frame(name, math, eng)
# 수학이 50점 이상인 사람만 출력
data[ (data$math >= 50) , ] name math eng
1 A 69 28
3 C 74 74
4 D 53 57
5 E 90 91
# 이름순 나열
data[ order(data$name), ] name math eng
1 A 69 28
2 B 19 85
3 C 74 74
4 D 53 57
5 E 90 91
# 총점을 계산하여 총점순으로 나열
total = data$math + data$eng
data = data.frame(data, total)
order.total = order(total, decreasing=TRUE)
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점으로 고정
data$math[ (data[ ,2] <= 50) ] = 50Remark. NA나 NULL은 문자형 상수가 아니다. 예를 들면, a = “NA”라고 입력하는 것과 a = NA라고 입력하는 것은 전혀 다르다.
name = c("A", "B", "C", "D", "E")
math = c(69, NA, 74, 53, 90)
eng = c(28, 85, 74, 57, NA)
eng2 = c(28, 85, 74, 57, NULL)
data = data.frame(name, math, eng)
# data2 = data.frame(name, math, eng2) # 에러 발생is.na(data$math)[1] FALSE TRUE FALSE FALSE FALSE
data$math == NA # c(NA, NA, NA, NA, NA) 출력될 것임 - 옳은 문법이 아님 [1] NA NA NA NA NA
data$name[ is.na(data$math) ][1] "B"
data$math[ is.na(data$math) ] = 0
data$eng[ is.na(data$eng) ] = 0
# 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=?)
a = c(7, 2, 30, 6, 9) ; X = matrix(1:16, ncol=4)
which(a >= 2)[1] 1 2 3 4 5
a[ (a >= 1) & (a <= 4) ] = NA
X[ (X %% 2) == 1 ] = 0
X[ upper.tri(X) ] = 1000
X[ row(X) > col(X) ] = 5000x = c(7, 2, 30, 6, 9)
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
x[ order(x) ][1] 2 6 7 9 30
name = c("DH", "YE", "SH", "YG", "JH", "YS", "HS")
math = c(69, 19, 74, 53, 90, 14, 67)
eng = c(28, 85, 74, 57, 91, 27, 14)
data = data.frame(name, math, eng)
data[ (data[ ,2] >= 50), ] # 수학이 50점 이상인 사람만 출력 name math eng
1 DH 69 28
3 SH 74 74
4 YG 53 57
5 JH 90 91
7 HS 67 14
data[ order(data[ ,1]), ] # 이름순 나열 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
# 총점을 계산하여 총점순으로 나열
total = as.vector(data[ ,2]) + as.vector(data[ ,3])
data = data.frame(data, total)
order.total = order(total, decreasing=TRUE)
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
mynorm = function(x) return( sum(x^2) )
maxmin = function(x) return( c(max(x), min(x)) )
X = matrix(1:16, 4, 4)
apply(X, 1, mean)[1] 7 8 9 10
apply(X, 2, mynorm)[1] 30 174 446 846