또 노트북을 구매했다. 옛날에 라디오 들으며 공부했다면 요즘 아이들은 유투브로 음악을 들으면서 공부를 하는가 보다. 그러다 보니 컴퓨터가 내 차례가 되질 않는다. 그래서 질렀다. 눈이 침침하니 크면 좋겠으나 지난번에 산 17인치는 사실 들고 다니는 노트북이 아니다. 그리고 키패드가 있으면 좋겠다. 14인치 이하는 키패드가 없다. 결국 15인치밖에 살게 없다. 역시 Lenovo IdeaPad Slim3가 저렴하다. 지난번에 산 17인치하고 다른 점은 화면이 크고, 배터리 용량이 3 cell(15인치는 2 cell) 이란 거 외에 차이점은 없는 거 같다. 인텔 Core i3이지만 10세대라 부팅속도나 크롬 브라우저 시작 속도가 빠르다. 그냥 간단한 인터넷, 영화보기에 이 정도면 부족함이 없어 보인다.
한 달에 노트북을 2대나 샀다. 안사람까지 1인 1노트북이 되었다.
박스 앞 면
박스 뒷면
본체와 충전기 포장 상태
본체와 충전기의 포장을 벗김. HDD를 달 수 있는 키트와 그냥 별 내용 없는 하지만 제조자 입장에서는 안 넣으면 안 되는 종이들.
위에 바라본 노트북. 그리 싼 티는 나지않는다. 플라스틱처럼 보이지는 않는다. 뭔지는 정확히 잘 모르겠다.
왼쪽. 전원, HDMI, 세 개의 USB
노트북 오른쪽. 이어폰 구멍. 마이크. SD 카드 리더.
뚜껑을 연 모습.
보호 종이 제거.
뒷 면은 플라스틱이다.
램과 SSD를 추가하기 위하여 뒷판을 열었다.
램을 추가하고, 가지고 있던 512G SSD 설치
8G 램 추가
원래 달려 있던 256G NVMe SSD. 웨스턴 디지탈 것인가 보다.
HDMI, USB 등
이어폰하고 SD 카드 리더.
뒷판을 덮었다.
이해가 가지 않는 것은 하드를 달기 어럽게 만들어 놓았다는 점이다. 배터리 고정 나사까지 풀고, HDD 업그레이드 키트의 선을 이용하여 메인보드와 연결하였다. 그냥 특정 부위에 하드를 끼면 되게 만들면 될 것을. 아마도 원가 절감 차원에서 그런 거 같다. 42만원 안 되게 주었으니 그 정도의 불편은 참는 수밖에.
인텔 Core i3 10th Gen. RAM 12Gb, NVMe 256G SSD, 512SSD. 이 정도면 good.
만 8년이 된 ASUS 노트북은 아직도 고장이 안나고 잘 돌아간다. ASUS 노트북은 죽지 않는다. 다만 느려질 뿐이다. 온라인 클래스만 아니어도 안 바꾸는데 온라인 클래스를 느린 컴퓨터로 듣는게 힘들다는 아이의 말에 바꾸지 않을 수가 없었다. 사실은 게임 관련 유투브 볼 때 고해상도로 보고 싶은 것이었는데 ...
느린 컴퓨터가 나쁜 것만은 아닌다. 아이가 게임을 하지 못한다. League of Legends를 하고 싶어도 안 돌아간다. 그래서 새 컴퓨터를 살 때의 기준은 인터넷, 온라인 클래스는 어느 정도 되지만 게임은 안되는 정도의 PC가 필요했다. 즉 현 시점에서 약간 후진 컴퓨터가 필요했다.(사실은 돈이 없어 저렴한 컴퓨터가 필요했다.)
데스크톱은 부피가 커서 이번에도 노트북 중 가장 화면이 큰 17인치 중에서, 그리고 적당한 CPU(Core i3)로 골랐다. 그래도 몇 년 쓸 노트북인데 셀러론이나 펜티엄 골드는 피하고 싶었다. 집에 놓고 항상 전기를 연결할 수 있으므로 배터리는 중요하지 않았다.
그리하여 고른 것이 Lenovo IdeaPad Slim3-17IML 3D 이다.
박스
노트북
왼쪽면. 전원. HDMI, USB 3개. 오른쪽 2개 USB가 고속.
오른쪽. 헤드폰, 마이크. SD 카드 리더. 이전 노트북(ASUS 노트북)은 CD-ROM 드라이브가 있었는데 이번 모델은 없다. 당장 CD로 설치하는 프로그램이 있는데 깔 수가 없다. 외장 CD-ROM 드라이브를 빌려서 깔아야 한다.
펼쳤을 때. 카메라 셔터가 있어서 안 쓸 때는 닫을 수 있다.
뒷면. 뒷면을 열고 8G 램을 설치하고, 1T HDD를 추가 했다. SLIM3가 단점도 있지만 이렇게 램과 HDD를 추가할 수 있는 점은 장점이라고 할 수 있다.
윈도우즈를 설치하고 부팅한 화면. 부팅은 정말 빠르다. 10초 이내인 것 같다. 그리고 노트북 뚜껑을 열면 바로 켜진다.
인터넷, 온라이 클래스, 문서, 엑셀, PPT 작업, 간단한 영화 보기에 적당한 컴퓨터이다. 이걸로 엄청난 게임을 못할 것이고, 동영상 편집도 못할 것이지만 난 그런 거 할 계획이 없으므로 우리집에 알맞은 컴퓨터로 보인다.
전체적인 기능은 비슷한데 자잘한 기능을 자꾸 넣어서 OS를 포함한 소프트웨어가 자꾸 느려지니 하드웨어를 바꿀 수 밖에 없다.
다형질 모형을 분석하는 것은 매우 큰 행렬을 다루는 것이다. 예를 1000마리를 유전평가한다고 하였을 때 single trait model의 경우 MME의 원소 수는 1000 * 1000으로 백만 개의 원소이나, 2 trait model의 경우 2000 * 2000으로 원소 수가 4백만 개로 늘어난다. n traits가 되면 원소 수는 n의 제곱이 된다. 그래서 다형질 모형을 자료 변환을 통하여 단형질 모형으로 분석할 방법을 고안하게 되었다.
여기서는 Canonical transformation을 통해서 다형질 모형을 단형질 모형으로 분석하는 방법을 소개한다. canonical transformaion matrix을 만들어 원래 자료에서 변환 자료를 만들고, 각각의 변환 자료를 단형질 모형으로 분석한다. 이후 단형질 모형의 육종가를 다시 canonical transformation matrix의 역행렬을 이용하여 변환하면 다형질 모형의 육종가와 동일하게 된다.
단 이 방법은 각 형질의 모형이 동일한 경우(same model) 그리고 결측치가 없는 경우(no missing value)에 사용할 수 있어 실제적으로 사용하기에 상당한 제한이 있다.
Linear Models for the Prediction of Animal Breeding Values 3rd Edition, Raphael A. Mrode.
Example 6.1 p97.
Example 5.1 p72에 나오는 다형질 모형을 canonical transformation matrix 이용하여 단형질 모형으로 분석하고 다시 단형질 분석의 육종가를 변환하는 과정
지금까지 여러 가지 모형의 육종가를 R로 구하였는데 모형이 복잡해지면서 R 프로그래밍 또한 복잡해 지고 있다. 각각의 모형에 알맞은 프로그램이 아니라 어느 정도 범용적으로 사용할 수 있는 프로그램을 만들어 보자. 본 내용은 Computational techniques in animal breeding, Ignacy Misztal (University of Georgia, Athens, USA)를 참고하였다. 위 책은 포트란 소스로 되어 있는데 그것을 R로 바꾸었다.
# Single trait 2 fixed effects least squares model
# Date : 2020.08.05
# Reference : Computational techneques in animal breeding, Ignacy Misztal
# MASS packages
if (!("MASS" %in% installed.packages())) {
install.packages("MASS", dependencies = TRUE)
}
library(MASS)
# function : find address
find_addresses <- function() {
for (i in 1:neff) {
if (i == 1) {
address[i] <<- indata[i]
} else {
address[i] <<- sum(nlev[1:i - 1]) + indata[i]
}
}
}
# parameters
# number of effects
neff = 2
neff
# number of levels for each effect
nlev = c(2, 3)
nlev
# number of equations
neq = sum(nlev)
neq
# make a empty left hand side
lhs = matrix(rep(0, neq * neq), nrow = neq)
lhs
# make a empty right hand side
rhs = matrix(rep(0, neq))
rhs
# addresses
address = c(rep(0, neff))
address
# set working directory setwd(choose.dir())
setwd("D:/temp/00_prediction")
# print working directory
getwd()
# read data : effect1, effect2, y1
data = read.table("01_lsq_data.txt", header = FALSE, sep = "", col.names = c("e1",
"e2", "y1"), stringsAsFactors = FALSE)
data
# number of data
ndata = nrow(data)
ndata
# fill lhs and rhs
for (k in 1:ndata) {
indata = as.numeric(data[k, 1:neff])
y = as.numeric(data[k, neff + 1])
find_addresses()
for (i in 1:neff) {
for (j in 1:neff) {
lhs[address[i], address[j]] = lhs[address[i], address[j]] + 1
}
rhs[address[i]] = rhs[address[i]] + y
}
}
# print lhs, rhs
lhs
rhs
# generalised inverse of lhs
gi_lhs = ginv(lhs)
# print
gi_lhs
# solution
sol = gi_lhs %*% rhs
# print
sol
실행 결과
> # MASS packages
> if (!("MASS" %in% installed.packages())) {
+ install.packages("MASS", dependencies = TRUE)
+ }
> library(MASS)
> # function : find address
> find_addresses <- function() {
+
+ for (i in 1:neff) {
+ if (i == 1) {
+ address[i] <<- indata[i]
+ } else {
+ address[i] <<- sum(nlev[1:i - 1]) + indata[i]
+ }
+ }
+
+ }
> # number of effects
> neff = 2
> neff
[1] 2
> # number of levels for each effect
> nlev = c(2, 3)
> nlev
[1] 2 3
> # number of equations
> neq = sum(nlev)
> neq
[1] 5
> # make a empty left hand side
> lhs = matrix(rep(0, neq * neq), nrow = neq)
> lhs
[,1] [,2] [,3] [,4] [,5]
[1,] 0 0 0 0 0
[2,] 0 0 0 0 0
[3,] 0 0 0 0 0
[4,] 0 0 0 0 0
[5,] 0 0 0 0 0
> # make a empty right hand side
> rhs = matrix(rep(0, neq))
> rhs
[,1]
[1,] 0
[2,] 0
[3,] 0
[4,] 0
[5,] 0
> # addresses
> address = c(rep(0, neff))
> address
[1] 0 0
> # set working directory setwd(choose.dir())
> setwd("D:/temp/00_prediction")
> # print working directory
> getwd()
[1] "D:/temp/00_prediction"
> # read data : effect1, effect2, y1
> data = read.table("01_lsq_data.txt", header = FALSE, sep = "", col.names = c("e1",
+ "e2", "y1"), stringsAsFactors = FALSE)
> data
e1 e2 y1
1 1 1 5
2 1 2 8
3 2 1 7
4 2 2 6
5 2 3 9
> # number of data
> ndata = nrow(data)
> ndata
[1] 5
> # fill lhs and rhs
> for (k in 1:ndata) {
+ indata = as.numeric(data[k, 1:neff])
+ y = as.numeric(data[k, neff + 1])
+
+ find_addresses()
+
+ for (i in 1:neff) {
+ for (j in 1:neff) {
+ lhs[address[i], address[j]] = lhs[address[i], address[j]] + 1
+ }
+ rhs[address[i]] = rhs[address[i]] + y
+ }
+
+ }
> # print lhs, rhs
> lhs
[,1] [,2] [,3] [,4] [,5]
[1,] 2 0 1 1 0
[2,] 0 3 1 1 1
[3,] 1 1 2 0 0
[4,] 1 1 0 2 0
[5,] 0 1 0 0 1
> rhs
[,1]
[1,] 13
[2,] 22
[3,] 12
[4,] 14
[5,] 9
> # generalised inverse of lhs
> gi_lhs = ginv(lhs)
> # print
> gi_lhs
[,1] [,2] [,3] [,4] [,5]
[1,] 0.44 -0.16 -0.04 -0.04 0.36
[2,] -0.16 0.24 0.06 0.06 -0.04
[3,] -0.04 0.06 0.39 -0.11 -0.26
[4,] -0.04 0.06 -0.11 0.39 -0.26
[5,] 0.36 -0.04 -0.26 -0.26 0.84
> # solution
> sol = gi_lhs %*% rhs
> # print
> sol
[,1]
[1,] 4.4
[2,] 4.4
[3,] 1.6
[4,] 2.6
[5,] 4.6
>
single traits 1 fixed effect least squares model with covariable
다음은 공변이(covariable)가 있는 최소 제곱 모형이다.
자료
1 1 5
1 2 8
2 1 7
2 2 6
2 3 9
첫 열은 분류 변수, 둘째 열이 공변이 변수이다.
프로그램
# single traits 1 fixed effect least squares model with covariable
# Date : 2020.08.05
# Reference : Computational techneques in animal breeding, Ignacy Misztal
# MASS packages
if (!("MASS" %in% installed.packages())) {
install.packages("MASS", dependencies = TRUE)
}
library(MASS)
# function : find address
find_addresses <- function() {
for (i in 1:neff) {
if (efftype[i] == "effcross") {
weight_cov[i] <<- 1
if (i == 1) {
address[i] <<- indata[i]
} else {
address[i] <<- sum(nlev[1:i - 1]) + indata[i]
}
} else if (efftype[i] == "effcov") {
weight_cov[i] <<- indata[i]
if (nestedcov[i] == 0) {
if (i == 1) {
address[i] <<- 1
} else {
address[i] <<- sum(nlev[1:i - 1]) + 1
}
} else if (nestedcov[i] > 0 && nestedcov[i] < neff) {
if (i == 1) {
address[i] <<- indata[nestedcov[i]]
} else {
address[i] <<- sum(nlev[1:i - 1]) + indata[nestedcov[i]]
}
} else {
warning("wrong descriptin of nested covariable")
}
} else {
warning("unimplemented effect type")
}
}
}
# parameters
# number of effects
neff = 2
neff
# effect type
efftype = c("effcross", "effcov")
efftype
# nested covariable
nestedcov = c(0, 1)
nestedcov
# nlev
nlev = c(2, 2)
nlev
# set working directory setwd(choose.dir())
setwd("D:/temp/00_prediction")
# print working directory
getwd()
# read data : effect1, effect2, y1
data = read.table("02_lsqr_data.txt", header = FALSE, sep = "", col.names = c("eff1",
"eff2", "y1"), stringsAsFactors = FALSE)
data
# number of data
ndata = nrow(data)
ndata
# number of equation
neq = sum(nlev)
neq
# make a empty left hand side
lhs = matrix(rep(0, neq * neq), nrow = neq)
lhs
# make a empty right hand side
rhs = matrix(rep(0, neq))
rhs
# addresses
address = rep(0, neff)
address
# weight of covariable
weight_cov = rep(0, neff)
weight_cov
# fill lhs and rhs
for (k in 1:ndata) {
# k = 1
indata = as.numeric(data[k, 1:neff])
y = as.numeric(data[k, neff + 1])
find_addresses()
for (i in 1:neff) {
for (j in 1:neff) {
lhs[address[i], address[j]] = lhs[address[i], address[j]] + weight_cov[i] * weight_cov[j]
}
rhs[address[i]] = rhs[address[i]] + y * weight_cov[i]
}
}
# print lhs, rhs
lhs
rhs
# generalised inverse of lhs
gi_lhs = ginv(lhs)
# print
gi_lhs
# solution
sol = gi_lhs %*% rhs
# print
sol
복잡한 것은 모르겠고, 다형질 임의회귀 모형(multiple trait random regression model)의 육종가까지는 구할 수 있다. 임의회귀 모형에서는 개체별로 회귀식을 추정하므로(개체별로 nested된 회귀식) MME에는 들어가지 않지만 어느 개체에 nested 할지를 알려 주어야 하므로 그에 따른 처리가 필요하다.
프로그램
# Best Linear Unbiase Prediction of Breeding Values
# Date : 2020.08.06.
# Reference : Computational techneques in animal breeding, Ignacy Misztal
# MASS packages
if (!("MASS" %in% installed.packages())) {
install.packages("MASS", dependencies = TRUE)
}
library(MASS)
# function : find address
find_addresses <- function() {
for (i in 1:neff) {
for (j in 1:ntrait) {
if (datum(i, j) == miss) {
address[i, j] <<- 0
weight_cov[i, j] <<- 0
next
}
baseaddr = ifelse(i == 1, j, sum(nlev[1:i - 1]) * ntrait + j)
if (effecttype[i] == "effcross") {
weight_cov[i, j] <<- 1
address[i, j] <<- baseaddr + (datum(i, j) - 1) * ntrait
} else if (effecttype[i] == "effcov") {
weight_cov[i, j] <<- datum(i, j)
if (nestedcov[i] == 0) {
address[i, j] <<- baseaddr
} else if (nestedcov[i] > 0 && nestedcov[i] < neff) {
address[i, j] <<- baseaddr + (datum(nestedcov[i], j) - 1) * ntrait
} else {
warning("wrong description of nested covariable")
}
} else if(effecttype[i] == "effnone") {
} else {
warning("unimplemented effect")
}
}
}
}
# return data in indata
datum <- function(ef, tr) {
return(indata[ef + (tr - 1) * neff])
}
# inverse of residual variance and covariance matrix
find_rinv <- function() {
tempr = r
for (i in 1:ntrait) {
if (y[i] == miss) {
tempr[i, ] = 0
tempr[, i] = 0
}
}
rinv <<- ginv(tempr)
}
# address for given level l of effect e and trait t
address1 <- function(e, l, t){
return(ifelse(e == 1, (l - 1) * ntrait + t, sum(nlev[1 : e - 1]) * ntrait + (l - 1) * ntrait + t))
}
# setup g
setup_g <- function(){
for(i in 1 : neff){
if (randomnumb[i] != 0){
g[,,i] <<- ginv(g0[,,i])
}
}
}
# add a genetic variance to the diagonal of left hand side
add_g_diag <- function(eff){
for(i in 1 : nlev[eff]){
for(j in 0 : (randomnumb[eff] - 1)){
for(k in 0 : (randomnumb[eff] - 1)){
for(t1 in 1 : ntrait){
for(t2 in 1 : ntrait){
m = address1(eff + j, i, t1)
l = address1(eff + k, i, t2)
#print(paste("i=",i,"j=",j,"k=",k,"t1=",t1,"t2=",t2,"m=",m,"l=",l))
lhs[m, l] <<- lhs[m, l] + g[t1 + j * ntrait, t2 + k * ntrait, eff]
}
}
}
}
}
}
# add genetic variacne matrix * NRN to left hand side
add_g_add <- function(type, eff){
if(type == 'g_A'){
w = c(1, -0.5, -0.5)
res = c(2, 4/3, 1, 0)
} else if(type == 'g_As'){
w = c(1, -0.5, -0.25)
res = c(16/11, 4/3, 16/15, 1)
}
for (di in 1:nped) {
p = as.numeric(pedi[di,])
ri = 1
if(p[2] == 0){ ri = ri + 1 }
if(p[3] == 0){ ri = ri + 1 }
mendel = res[ri]
for(i in 0 : (randomnumb[eff] - 1)){
for(j in 0 : (randomnumb[eff] - 1)){
for(t1 in 1 : ntrait){
for(t2 in 1 : ntrait){
for (k in 1 : 3) {
for (l in 1 : 3) {
if (p[k] != 0 && p[l] != 0) {
m = address1(eff + i, p[k], t1)
n = address1(eff + j, p[l], t2)
a[p[k], p[l]] <<- a[p[k], p[l]] + w[k] * w[l] * mendel
lhs[m, n] <<- lhs[m, n] + g[t1 + i * ntrait, t2 + j * ntrait, eff] * w[k] * w[l] * mendel
}
}
}
}
}
}
}
}
}
# parameters
# number of traits
ntrait = 2
ntrait
# number of effects
neff = 2
neff
# type of effects : cross-classified or covariable
effecttype = c("effcross", "effcross")
effecttype
# 0 means cross-classified or not nested, 1 means # of effect within which covariable is nested
nestedcov = c(0, 0)
nestedcov
# level of effect, level of covariable depends on if it is nested or not
nlev = c(2, 5)
nlev
# missing values trait/effect
miss = 0
miss
# type of random effect : g_fixed, g_diag, g_A, g_As
randomtype = c("g_fixed", "g_A")
randomtype
# number of correlated effects per effect
randomnumb = c(0, 1)
randomnumb
# genetic varinace and covariance matrix for each trait
vardim = ntrait * max(randomnumb)
g0 = array(c(0), dim =c(vardim, vardim, neff))
# genetic variance matrix for effect 2
g0[,,2] = matrix(c(2, -1, -1, 1), nrow = vardim)
g0
# matrix for inverse of genetic variance matrix
g = array(c(0), dim =c(vardim, vardim, neff))
setup_g()
g
# residual variace
r = matrix(c(1, 0, 0, 1), nrow = ntrait)
r
# empty inverse of r
rinv = matrix(c(0), nrow = ntrait, ncol = ntrait)
rinv
# number of equations
neq = ntrait * sum(nlev)
neq
# make empty lhs and rhs
lhs = matrix(c(0), nrow = neq, ncol = neq)
lhs
rhs = matrix(c(0), nrow = neq)
rhs
# addresses
address = matrix(c(0), nrow=neff, ncol=ntrait)
address
# weight of covariable
weight_cov = matrix(c(0), nrow=neff, ncol=ntrait)
weight_cov
# set working directory setwd(choose.dir())
setwd("D:/temp/00_prediction")
# print working directory
getwd()
# read data : t1e1, t1e2, t2e1, t2e2, y1, y2
data = read.table("06_mt_lsq_data.txt", header = FALSE, sep = "", col.names = c("t1e1", "t1e2", "t2e1", "t2e2", "y1", "y2"), stringsAsFactors = FALSE)
data
# number of data
ndata = nrow(data)
ndata
# read pedigree : animal, sire, dam
pedi = read.table("04_stam_pedi.txt", header = FALSE, sep = "", col.names = c("animal",
"sire", "dam"), stringsAsFactors = FALSE)
pedi
# number of pedigree
nped = nrow(pedi)
nped
# inverse matrix of NRM(Nemerator Relationship Matrix)
a = matrix(c(0), nrow = nped, ncol = nped)
a
# loop data
for (di in 1:ndata) {
indata = as.numeric(data[di, 1:(ntrait * neff)])
y = as.numeric(data[di, (ntrait * neff + 1):(ntrait * (neff + 1))])
# address and weight_cov
find_addresses()
# inverse of r
find_rinv()
for (i in 1:neff) {
for (j in 1:neff) {
for (k in 1:ntrait) {
for (l in 1:ntrait) {
lhs[address[i, k], address[j, l]] = lhs[address[i, k], address[j, l]] + weight_cov[i, k] * weight_cov[j, l] * rinv[k, l]
}
}
}
for (k in 1:ntrait) {
for (l in 1:ntrait) {
rhs[address[i, k]] = rhs[address[i, k]] + weight_cov[i, k] * rinv[k, l] * y[l]
}
}
}
}
# print
lhs
rhs
# random effects' contributions
for(i in 1 : neff){
if(randomtype[i] == 'g_fixed'){
next
} else if(randomtype[i] == 'g_diag'){
add_g_diag(i)
} else if(randomtype[i] == 'g_A' || randomtype[i] == 'g_As'){
add_g_add(randomtype[i], i)
} else {
warning("unimplemented random type")
}
}
# print lhs
lhs
# generalised inverse of lhs
gi_lhs = ginv(lhs)
# print
gi_lhs
# solution
sol = gi_lhs %*% rhs
# print
sol
# write a solution by effect, level and trait
# copy the continuous variances to the original effects
for(i in 1 : neff){
if (randomnumb[i] > 1){
for(j in 2 : randomnumb[i]){
first = ntrait * (j - 1) + 1
last = ntrait * j
print(paste(i, j, first, last, (neff + j - 1)))
g0[1 : ntrait, 1 : ntrait, (i + j - 1)] = g0[first : last, first : last, i]
}
}
}
line = c("effect level trait solution sep rel")
write(line, file = "solutions")
for(e in 1 : neff){
# when the effect is used
if(nlev[e] > 0){
for(l in 1 : nlev[e]){
for(t in 1 : ntrait){
j = address1(e, l, t)
sep2 = gi_lhs[j, j]
# when the effect is random
rel = ifelse(randomtype[e] != 'g_fixed',1 - sep2 / g0[t, t, e], 0)
line = paste(e, l, t, sol[j], sqrt(sep2), rel)
write(line, file = "solutions", append = TRUE)
}
}
}
}
앞에서는 각 형질의 모형이 같다고 가정하였다. 즉 각 형질에 동일한 고정 효과와 임의 효과(effect)가 들어간다는 뜻이다. 각 형질의 모형이 다를 때, 즉 모형에 포함된 효과(effect)가 다른 경우를 다룬다. 예를 들어 hys1은 첫번째 형질에만 해당되고, hys2는 두번째 형질에만 해당되는 경우이다. 비록 모형이 다르더라도 모형이 같다고 가정해야 traits in animal(effect) 방식으로 프로그램을 할 수 있다.
첫째 컬럼은 animal이다. 둘째 컬럼은 hys1인데 첫째 형질의 모형에만 들어간다. 셋째 컬럼은 hys2인데 둘째 형질의 모형에만 들어간다. 넷째는 fat1으로 1산 유지량 형질, 다섯째는 fat2로 2산 유지량이다. 비록 hys1이 첫째 형질에만 hys2가 둘째 형질에만 있지만, 두 고정효과 모두 양 쪽 형질의 모형에 있다고 가정한다. 그래서 same model이라고 하면 다음과 같이 design matrix가 만들어질 것이다.
그러나 사실 hys1은 형질 2에 없고, hys2는 형질 1에 없으므로 다음과 같이 만들어진다.
위는 효과 내에, 형질 내에, 레벨이 나오는데 이것은 형질 -> 레벨 -> 형질의 순으로 바꾸어 생각한다.
위의 design matrix에서 4번 개체가 LHS에 기여하는 바는 다음과 같다. R의 inverse를 곱하여 얻은 값이다.
총 9개의 네 모칸이 나오는데 그것은 hys1, hys2, animal 각각 교차하여 차지하는 칸이다. 그런데 hys1은 첫째 형질의 모형에만 있으므로 R의 inverse 앞 뒤에 [ [ 1, 0], [0, 0] ]을 곱하여 준다. 구체적으로 다음과 같다.