2017-04-20 1 views
2

그래서 병합해야하는 세 가지 데이터 세트가 있습니다. 여기에는 4 학년과 5 학년의 학교 데이터 및 읽기/수학 점수가 포함됩니다. 그 중 하나는 일부 변수에서 누락 된 부분이 많은 긴 형식의 데이터 집합 (예, 긴 형식의 데이터가 필요함)이고 나머지 두 가지는 와이드 형식의 전체 누락 데이터 이러한 모든 데이터 프레임에는 데이터베이스의 각 개인에 대해 고유 한 ID 번호가있는 열이 있습니다. school_lf, school4school5을 : 여기 와이드 폼 데이터로 NAs가있는 NAs를 오버라이드 할 수 있도록 긴 형식 데이터 병합

내가 다음과 같다 사용할 필요가 세 개의 데이터 프레임 ... 함께 일하고 data.frames의 유형의 작은 예를 생성하는 완전 재현 예이다. school_lf는 NAS 및 school4school5와 긴 형식의 데이터가 나는 넓은 형태의 데이터를 병합 할 필요가

set.seed(890) 
school <- NULL 
school$id <-sample(102938:999999, 100) 
school$selected <-sample(0:1, 100, replace = T) 
school$math4 <- sample(400:500, 100) 
school$math5 <- sample(400:500, 100) 
school$read4 <- sample(400:500, 100) 
school$read5 <- sample(400:500, 100) 
school <- as.data.frame(school) 

# Delete observations at random from the school df 

indm4 <- which(school$math4 %in% sample(school$math4, 25)) 
school$math4[indm4] <- NA 

indm5 <- which(school$math5 %in% sample(school$math5, 50)) 
school$math5[indm5] <- NA 

indr4 <- which(school$read4 %in% sample(school$read4, 70)) 
school$read4[indr4] <- NA 

indr5 <- which(school$read5 %in% sample(school$read5, 81)) 
school$read5[indr5] <- NA 

# Separate Read and Math 
read <- as.data.frame(subset(school, select = -c(math4, math5))) 
math <- as.data.frame(subset(school, select = -c(read4, read5))) 

# Now turn this into long form data... 
clr <- melt(read, id.vars = c("id", "selected"), variable.name = "variable", value.name = "readscore") 
clm <- melt(math, id.vars = c("id", "selected"), value.name = "mathscore") 

# Clean up the grades for each of these... 
clr$grade <- ifelse(clr$variable == "read4", 4, 
      ifelse(clr$variable == "read5", 5, NA)) 

clm$grade <- ifelse(clm$variable == "math4", 4, 
      ifelse(clm$variable == "math5", 5, NA)) 

# Put all these in one df 
school_lf <-cbind(clm, clr$readscore) 
school_lf$readscore <- school_lf$`clr$readscore` # renames 
school_lf$`clr$readscore` <- NULL # deletes 
school_lf$variable <- NULL # deletes 

############### 


# Generate the 2 data frames with IDs that have the full data 

set.seed(890) 
school4 <- NULL 
school4$id <-sample(102938:999999, 100) 
school4$selected <-sample(0:1, 100, replace = T) 
school4$math4 <- sample(400:500, 100) 
school4$read4 <- sample(400:500, 100) 
school4$grade <- 4 
school4 <- as.data.frame(school4) 


set.seed(890) 
school5 <- NULL 
school5$id <-sample(102938:999999, 100) 
school5$selected <-sample(0:1, 100, replace = T) 
school5$math5 <- sample(400:500, 100) 
school5$read5 <- sample(400:500, 100) 
school5$grade <- 5 
school5 <- as.data.frame(school5) 

(idgrade에 의해) NA의이 긴 형식의 데이터를 채우는 데 사용하는 데 필요한 DFS는 긴 형식 데이터로 NAs를 실제 값으로 바꿉니다. 아래 코드를 시도했지만 NA가있는 곳에 읽기 점수와 수학 점수를 병합하는 대신 여러 열을 소개합니다. 6 개의 개별 열 (read.x, , math.x, math.y, mathscorereadscore) 대신에 읽기 점수가있는 열과 수학 점수가있는 열이 하나만 있으면됩니다.

sch <- merge(school_lf, school4, by = c("id", "grade", "selected"), all = T) 
sch <- merge(sch, school5, by = c("id", "grade", "selected"), all = T) 

도움을 주신 데 대해 감사드립니다. 나는 이것을 몇 시간 동안 풀려고 노력했지만 아무런 진전을 이루지 못했다. (그래서 나는 여기서 물어 보았다)

답변

0

dplyrcoalesce 함수를 사용할 수있다. 첫 번째 벡터의 값이 NA이면 두 번째 벡터의 동일한 위치에있는 값이 NA가 아닌지 확인하고 선택합니다. 다시 NA라면 3 번째로갑니다.

library(dplyr) 
sch %>% mutate(mathscore = coalesce(mathscore, math4, math5)) %>% 
    mutate(readscore = coalesce(readscore, read4, read5)) %>% 
    select(id:readscore) 
+0

덕분에 그 기능이 깔끔하게 보인다!! 환영보다 더 많은,하지만 난 문제가 무엇을하는지 이해하는 데 ... 내가 샘플 데이터로 실행 시도하고 나에게 오류를 제공합니다 :'mutate_impl (.data, dots)의 오류 : 'math4'객체를 찾을 수 없습니다. ' – rowbust

+0

그러면 다른 데이터 세트에서 실행하고있을 것입니다. math4가 함수를 적용하는 데이터 세트에없는 것입니다. 에. – Edwin

0

편집 : 난 그냥 내 실제 데이터에 접근을 시도하고 대체 데이터는 결과적으로 DFS 내가 번호를 다른 한으로 coalesce을하려고, 일부의 NA를 가지고 있기 때문에 작동하지 않습니다 행 중 ... 사각형으로 돌아갑니다.

다음 코드를 사용하여이 코드를 이해할 수 있었지만 (가장 우아하고 직선적이지는 않지만 @ Edwin의 응답으로 올바른 방향으로 나를 안내 할 수있었습니다.)이 코드를 더 우아하게 만드는 방법에 대한 제안 효율적인 대응을위한

# Idea: put both in long form and stack on top of one another... then merge like that! 

sch4r <- as.data.frame(subset(school4, select = -c(mathscore))) 
sch4m <- as.data.frame(subset(school4, select = -c(readscore))) 

sch5r <- as.data.frame(subset(school5, select = -c(mathscore))) 
sch5m <- as.data.frame(subset(school5, select = -c(readscore))) 


# Put these in LF 
sch4r_lf <- melt(sch4r, id.vars = c("id", "selected", "grade"), value.name = "readscore") 
sch4m_lf <- melt(sch4m, id.vars = c("id", "selected", "grade"), value.name = "mathscore") 

sch5r_lf <- melt(sch5r, id.vars = c("id", "selected", "grade"), value.name = "readscore") 
sch5m_lf <- melt(sch5m, id.vars = c("id", "selected", "grade"), value.name = "mathscore") 

# Combine in one DF 
sch_full_4 <-cbind(sch4r_lf, sch4m_lf$mathscore) 
sch_full_4$mathscore <- sch_full_4$`sch4m_lf$mathscore` 
sch_full_4$`sch4m_lf$mathscore` <- NULL # deletes 
sch_full_4$variable <- NULL 

sch_full_5 <- cbind(sch5r_lf, sch5m$mathscore) 
sch_full_5$mathscore <- sch_full_5$`sch5m$mathscore` 
sch_full_5$`sch5m$mathscore` <- NULL 
sch_full_5$variable <- NULL 

# Stack together 
sch_full <- rbind(sch_full_4,sch_full_5) 
sch_full$selected <- NULL # delete this column... 

# MERGE together 
final_school_math <- mutate(school_lf, mathscore = coalesce(school_lf$mathscore, sch_full$mathscore)) 
final_school_read <- mutate(school_lf, readscore = coalesce(school_lf$readscore, sch_full$readscore)) 

final_df <- cbind(final_school_math, final_school_read$readscore) 
final_df$readscore <- final_df$`final_school_read$readscore` 
final_df$`final_school_read$readscore` <- NULL 
관련 문제