티스토리 뷰
문제의 핵심은 너무 지엽적인 문제에 몰두하게 되어
전체적인 스케쥴을 보지 못한다는 것이다.
예를 들어,
렘펠-지브 복잡도를 계산하는 R function을 만들었다.
lempel.ziv=function(s, alphabet) {
n=sum(!is.na(s))
s=s[!is.na(s)]
if (sum(s %in% alphabet)!= n) { stop("Alphabet error!") }
voc=s[1]; cmpl=1
r=1; i=1;
while (r+i<=n) {
Q="";
repeat {
Q=paste(Q,s[r+i], sep="")
if (Q %in% voc) {
cmpl[r+i]=cmpl[r+i-1]; i=i+1; }
if(!(Q %in% voc) | !(r+i<=n)) { break }
} # repeat
if (r+i > n) break;
voc=c(voc, Q); cmpl[r+i]=cmpl[r+i-1]+1;
r=r+i; i=1;
}
cmpl=cmpl/(1:n/log(1:n,length(alphabet)))
return(cmpl)}
하지만 이 function은 NA를 무시하도록 만들어졌다.
따라서 NA를 포함된 문자열을 계산하면 길이가 다른 렘펠-지브 복잡도 벡터가 생성된다.
NA를 적절히 처리하도록 function를 수정하고 싶다.
문제는 이 function을 만든지 1달은 되었기 때문에
function을 수정하기엔 힘이 좀 들거란 거다. 시간도!
이 때는 임시방편을 사용하는 수 밖에 없다.
Data를 적절히 손질해서 어떻게든 굴러만 가게 해야 한다!
하지만 나는 그러지 못했다.
장장 3시간 동안 NA를 제대로 처리하는 function lempel.ziv를 만들었다.
### lempel.ziv
### with handling NAs
### ver. 14-8-23 from snippets.R
###
lempel.ziv=function(s, alphabet=unique(s)[!is.na(unique(s))], na.action=getOption("na.action"), na.new.element=NA) {
if (any(is.na(alphabet))) {
alphabet=na.omit(alphabet)
warning("any NA's in alphabet will be ignored.") }
if(!is.atomic(s)) stop("vector input needed!")
# integrity check
if(identical(na.action, na.omit) & !is.na(na.new.element)) { warning("NA's omitted but new letter for NA!")}
s=na.action(s)
n=length(s)
if (n==0) { return(c()) }
if(!is.na(na.new.element)) {
s[is.na(s)]=na.new.element
if (!(na.new.element %in% alphabet)) {alphabet=c(alphabet,na.new.element)}
else {warning("NAs are converted to a letter which exists already in alphabet!")}
}
if(length(alphabet) != length(unique(alphabet))) { warning("Alphabet lettters possibly duplicated")}
if (sum(s[!is.na(s)] %in% alphabet)!= sum(!is.na(s))) { stop("Alphabet error!") }
if (all(is.na(s))) { cmpl=rep(NA,n); names(cmpl)=s; return(cmpl)}
r=min(which(!is.na(s))); i=1;
v.n=c(rep(0,r-1),1); voc=s[r]; cmpl=c(rep(0,r-1),1)
while (r+i<=n) {
Q="";
repeat {
if (!is.na(s[r+i])) {
Q=paste(Q,s[r+i], sep="")
if (Q %in% voc) {
cmpl[r+i]=cmpl[r+i-1]; v.n[r+i]=v.n[r+i-1]+1; i=i+1;}
if(!(Q %in% voc) | !(r+i<=n)) { break }
} else { cmpl[r+i]=cmpl[r+i-1]; v.n[r+i]=v.n[r+i-1]; i=i+1; if (r+i > n) break; }
} # repeat
if (r+i > n) break;
voc=c(voc, Q); cmpl[r+i]=cmpl[r+i-1]+1; v.n[r+i]=v.n[r+i-1]+1;
r=r+i; i=1;
}
if (length(alphabet) > 1) {
cmpl=cmpl/(v.n/log(v.n,length(alphabet))) }
else { cmpl=cmpl*0 }
cmpl[!is.finite(cmpl)]=NA # for NaN when first elements are NA's
names(cmpl)=s
return(cmpl)
}
처음 이 function을 만들 때 2시간 걸렸는데...
이것이야말로 trial-and-error 기법의 전형이다.
guard rail에 차를 부딪치며 운전하는 방법이라고 하던데...
이상향은 hammock-driven인데...
근데 나는 CS(Computer Science) 전공도 아닌데
왜 coding(사회과학에서 말하는 coding 말고)이나 하고 있는 걸까?
이 function은 두 가지 결정을 사용자측에서 내려야 한다.
1. NA를 지울 것인가, 말 것인가?
na.action=na.omit # 지우자
na.action=na.pass # 지우지 말자
2. NA를 또다른 letter로 생각할 것인가? 아니면 없는 문자로 생각할 것인가?
na.new.element=0 # NA를 0으로 바꾸자.
na.new.element=NA # NA는 건너뛰자.
그래서 결론은,
위의 함수를 만드느라 논문을 빨리 쓰지 못하게 됐다는 것.
그리고 의문,
나는 왜 CS 전공도 아닌데, 이 함수나 만들고 있는가?
그런데 CS 말이 나와서 말인데,
프로그램을 만들 때 주의할 점은 boundary condition을 잘 고려해야 한다는 것이다.
예를 들어, R에서,
nchar("R rocks!")는 8이다.
nchar("")는 0이다.
그렇다면 nchar(NA)는?
- Total
- Today
- Yesterday
- 추단법
- 접근 프레임
- 긍정 언어
- 절차중심 프레임
- 용어정리
- 준비 프레임
- 티모시 윌슨
- Schoemaker
- 앤드류 양
- Decisive
- 지금여기 프레임
- 닮고 싶은 사람
- 의미중심 프레임
- 열린마음
- How We Decide
- 기본 소득
- 자신있게 결정하라
- 비교 프레임
- Free Dividend
- 모짜르트 효과
- 의사결정
- 리더십
- 회피 프레임
- 탁월한 결정의 비밀
- 절대 프레임
- Andrew Yang
- Edward Russo
- 뇌과학
- Technology is new oil
- 이기는 결정
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |