아이티윌_데이터 분석 55기/문제풀이_통계 및 분석

#4-2. 4일차 퀴즈에 대한 문제풀이

ecosso 2026. 4. 2. 18:01

1. 2000-2013년_연령별실업율_40-49세.csv 파일을 읽고
df1 <- read.csv('2000-2013년_연령별실업율_40-49세.csv', fileEncoding = 'cp949')

 

1) 월별 평균

 

더보기

[내 답안]

 

df1
names(df1) <- str_remove_all(names(df1), 'X|년')

df1$avg_month <- apply(df1, 1, mean)
df1$avg_month <- round(df1$avg_month, 1)

df1

 

 

[문제풀이]

 


apply(df1[,-1],1,mean)

 

 

2) 연도별 평균

 

더보기

[내 답안]

 

avg_year <- apply(df1, 2, mean)
round(avg_year, 1)

 

 

[문제풀이]

 

apply(df1[,-1],2,mean)

 

 

2. df_score.csv 파일을 읽고 다음을 처리하여라.
 id는 학생번호이며 각 과목별 응시를 여러번 한 시험성적이 score에 저장.
 score가 NA인 경우는 미응시를 의미한다고 가정
df2 <- read.csv('df_score.csv', fileEncoding = 'cp949')

# 1) 학생별로 과목당 응시횟수 출력

 

더보기

[내 답안]

 

str(df2)
head(df2)

df2

ddply(df2, .(id,subject), summarise, n = sum(!is.na(score)))

 

 

[문제풀이]

 

df3 <- df2[!is.na(df2$score), ] # 응시 데이터만 따로 저장

ddply(df3, .(id,subject), summarise, 응시횟수 = length(score)) # 벡터의 수를 length로 확인

 

 

2) 각 과목별로 시험을 가장 잘본 학생의 id 출력
 단, 여러번 응시한 경우는 평균으로 최종 시험성적을 판단한다.

 

더보기

[내 답안]

 

ddply(df2, .(subject), summarise, max_score = max(score, na.rm=T)), [,c('id','subject','score')]
ddply(df2, .(id, subject), transform, max_score = max(mean(score), na.rm=T))


df3 <- ddply(df2, .(id, subject), summarise, m = mean(score, na.rm = T))


df4 <- ddply(df3, .(subject), transform, max_score = max(m, na.rm = T))
df4[!is.na(df4$m) & df4$m == df4$max_score, c('id', 'subject', 'max_score')]

 

 

[문제풀이]

 

df3
df4 <- ddply(df3, .(id,subject), summarise, 성적 = mean(score)) 
ddply(df4, .(subject), subset, 성적 == max(성적))

 

 

3. 아래 명령어 실행 후
dis <- read.table('disease.txt', header = T, fileEncoding = 'cp949')   
 1) dis와 동일한 dis1 생성 후 각 NA값을 각 컬럼의 최소값으로 수정(min)

 

더보기

[내 답안]

 

str(dis)
head(dis)

dis1 <- dis

dis[is.na(dis[,2]),][, 2]
min(dis[,2], na.rm=T)

dis[is.na(dis[,3]),][, 3] <- min(dis[,3], na.rm=T)


for (i in 1:ncol(dis1)) {
  dis1[is.na(dis1[, i]), i] <- min(dis1[, i], na.rm = TRUE)
}
dis1

 

 

[문제풀이]

 

# 방법1) 직접 모든 컬럼마다 수정
dis1 <- dis
dis1$콜레라[is.na(dis1$콜레라)] <- min(dis1$콜레라, na.rm= T)
dis1$장티푸스[is.na(dis1$장티푸스)] <- min(dis1$장티푸스, na.rm= T)
...

# 방법2) for문 사용


## 컬럼이름 반복
for (i in names(dis1)[-1]) {
  dis1[,i][is.na(dis1[,i])] <- min(dis1[,i], na.rm=T)
}

## 컬럼위치 반복
for (i in 2:ncol(dis1)) {
  dis1[,i][is.na(dis1[,i])] <- min(dis1[,i], na.rm=T)
}

# 방법3) 적용함수
f1 <- function(x) {
  x[is.na(x)] <- min(x, na.rm = T)
  return(x)
}
dis1[,-1] <- apply(dis1[,-1],2,f1)
dis1

 

 

2) A형간염의 컬럼 이름을 A간염으로 변경(dis1에서)

 

더보기

[내 답안]

 

names(dis1)[6] 
names(dis1) <- str_replace(names(dis1), "A형간염", 'A간염')
dis1

 

 

[문제풀이]

 

names(dis1)[6] <- 'A간염'

 

 

4. student.csv, exam_01 파일을 읽고 각 학생의 이름, 성적, 학점 출력
 단, 학점은 90이상이면 A, 70이상이면 B, 70 미만이면 C로 정의

 

더보기

[내 답안]

 

std <- read.csv('student.csv', fileEncoding = 'cp949')
std

exa <- read.csv('exam_01.csv', fileEncoding = 'cp949')
exa

stde <- merge(std, exa, by = 'STUDNO')

stde$학점 <- ifelse(stde$TOTAL >= 90, 'A',
                    ifelse(stde$TOTAL < 70, 'C', 'B'))

stde[,c('NAME','TOTAL','학점')]

 

 

[문제풀이]

 

std <- read.csv('student.csv', fileEncoding = 'cp949')
exam <- read.csv('exam_01.csv', fileEncoding = 'cp949')
std2 <- merge(std,exam)[,c('NAME', 'TOTAL')]

# for문)
a1 <- c()
for (i in std2$TOTAL) {
  if (i >= 90) {
    a1 <- c(a1,'A')
  } else if (i >= 70) {
    a1 <- c(a1,'B')
  } else {
    a1 <- c(a1,'C')
  }
}

# sapply)
f1 <- function(x) {
  if (x >= 90) {
    res <- 'A'
  } else if (x >= 70) {
    res <- 'B'
  } else {
    res <- 'C'
  }
  return(res)
}
sapply(std2$TOTAL, f1)

 

 

5. read_test.csv 파일을 읽고 일자별 총합, 항목(a~d)별 총합
 단, . 또는 - 또는 ? 또는 ! 또는 null는 0으로 치환 후 처리
test1 <- read.csv('read_test.csv')

f1 <- function(x) {
  if (x %in% c('.','-','?','!', 'null')) {
    return('0')
  } else {
    return(x)
  }
}

더보기

[내 답안]

 

test1 <- apply(test1, c(1,2), f1)
test1<-as.data.frame(test1)

for (i in 2:ncol(test1)) {
  test1[, i] <- as.numeric(test1[, i])
}


test1$total <- apply(test1[,-1],1,sum)

 


apply(test1[,-1],2,sum,na.rm=T)

 

[문제풀이]

 

# 벡터의 반복
sapply(test1$a, f1) 
# 데이터프레임의 원소별 반복
test1[,-1] <- apply(test1[,-1], 2, f1) # apply에 의한 test1의 각 컬럼별(벡터)로 f1에 전달, f1은 스칼라에 대해서만 연산 가능
test1[,-1] <- apply(test1[,-1], c(1,2), f1)
str(test1)
# 각 컬럼별 숫자변경) 컬럼별 as.numeric 함수의 적용
test1[,-1] <- apply(test1[,-1], 2, as.numeric)