2015-02-27 3 views
1

У меня есть dataframe следующим образом:Пустые строки в списке в качестве значений NA в data.frame в R

hospital <- c("PROVIDENCE ALASKA MEDICAL CENTER", "ALASKA REGIONAL HOSPITAL", "FAIRBANKS MEMORIAL HOSPITAL", 
      "CRESTWOOD MEDICAL CENTER", "BAPTIST MEDICAL CENTER EAST", "ARKANSAS HEART HOSPITAL", 
      "MEDICAL CENTER NORTH LITTLE ROCK", "CRITTENDEN MEMORIAL HOSPITAL") 
state <- c("AK", "AK", "AK", "AL", "AL", "AR", "AR", "AR") 
rank <- c(1,2,3,1,2,1,2,3) 
df <- data.frame(hospital, state, rank) 
df 

           hospital state  rank 
    1 PROVIDENCE ALASKA MEDICAL CENTER  AK  1 
    2 ALASKA REGIONAL HOSPITAL    AK  2 
    3 FAIRBANKS MEMORIAL HOSPITAL    AK  3 
    4 CRESTWOOD MEDICAL CENTER    AL  1 
    5 BAPTIST MEDICAL CENTER EAST    AL  2 
    6 ARKANSAS HEART HOSPITAL     AR  1 
    7 MEDICAL CENTER NORTH LITTLE ROCK  AR  2 
    8 CRITTENDEN MEMORIAL HOSPITAL   AR  3 

Я хотел бы создать функцию, rankall, который принимает ранг в качестве аргумента и возвращает больницы этого ранга для каждого государства, при этом НС возвращаются, если в штате нет больницы, которая соответствует данному рангу. Например, я хочу вывод rankall (ранг = 3), чтобы выглядеть следующим образом:

      hospital  state 
    AK FAIRBANKS MEMORIAL HOSPITAL  AK  
    AL       <NA>  AL 
    AR CRITTENDEN MEMORIAL HOSPITAL  AR  

Я пробовал:

rankall <- function(rank) { 
split_by_state <- split(df, df$state) 
ranked_hospitals <- lapply(split_by_state, function (x) { 
    x[(x$rank==rank), ] 
}) 
combined_ranked_hospitals <- do.call(rbind, ranked_hospitals) 
return(combined_ranked_hospitals[ ,1:2]) 
} 

Но rankall (ранг = 3) возвращает:

        hospital  state  
    AK  FAIRBANKS MEMORIAL HOSPITAL   AK       
    AR  CRITTENDEN MEMORIAL HOSPITAL  AR    

Это не учитывает значения NA, которые мне нужно отслеживать. Есть ли способ, чтобы R распознавал пустые строки в моем объекте списка в моей функции как NA, а не как пустые строки? Есть ли еще одна функция, кроме того, что было бы более полезно для этой задачи?

[Примечание: этот информационный кадр - курс Курса программирования Курсера. Это также мой первый пост в Stackoverflow, и я впервые изучал программирование. Спасибо всем, кто предложил решения и советы, этот форум является фантастическим. ]

+0

Это курс Курсера. Пожалуйста, отдайте должное кредиту. – KFB

ответ

1

Вам просто нужно в файле/еще в вашей функции:

rankall <- function(rank) { 
    split_by_state <- split(df, df$state) 
    ranked_hospitals <- lapply(split_by_state, function (x) { 
     indx <- x$rank==rank 
     if(any(indx)){ 
      return(x[indx, ]) 
     else{ 
      out = x[1, ] 
      out$hospital = NA 
      return(out) 
     } 
    } 
} 
+0

Это замечательно @Jthorpe, так как ваше решение позволяет мне работать с базой R. Спасибо! – carozimm

0

Я считаю, что это полезно использовать dplyr. Единственное, что странно, суммирует жалобы, когда я использую NA вместо "NA". У кого-нибудь есть мысли о том, почему?

library(dplyr) 
rankall <- function(chosen_rank){ 
    group_by(df, state) %>% 
    summarize(hospital = ifelse(length(hospital[rank==chosen_rank])!=0, 
           as.character(hospital[rank==chosen_rank]), "NA"), 
       rank = chosen_rank) 
} 

rankall(1) 
rankall(2) 
rankall(3) 
+0

Спасибо, Алекс, это работает! – carozimm

1

Вот альтернативный подход:

rankall <- function(rank) { 
    do.call(rbind, lapply(split(df, df$state), function(df) { 
    tmp <- df[df$rank == rank, 1:2] 
    if (!nrow(tmp)) return(transform(df[1, 1:2], hospital = NA)) else return(tmp) 
    })) 
} 
rankall(3) 
# hospital state 
# AK FAIRBANKS MEMORIAL HOSPITAL AK 
# AL       <NA> AL 
# AR CRITTENDEN MEMORIAL HOSPITAL AR 
1

Вот еще один dplyr подход.

fun1 <- function(x) { 
      group_by(df, state) %>% 
      summarise(hospital = hospital[x], 
         rank = nth(rank, x)) 
     } 

# fun1(3) 
#Source: local data frame [3 x 3] 
# 
# state      hospital rank 
#1 AK FAIRBANKS MEMORIAL HOSPITAL 3 
#2 AL       NA NA 
#3 AR CRITTENDEN MEMORIAL HOSPITAL 3 
Смежные вопросы