Проблема конкатенации символьного вектора в цикле for - возврат только конечного объекта - PullRequest
0 голосов
/ 31 мая 2019

Я пытаюсь просмотреть список данных о больницах в каждом штате и извлечь больницу, которая соответствует указанному ранжированию (аргумент num). Мне нужно вернуть фрейм данных с двумя столбцами, больницами и штатами, в котором указана больница в каждом штате с указанным ранжированием для указанного результата, поэтому должно быть 50 строк.

Проблема в том, что я получаю возвращенный фрейм данных только с одной строкой, содержащей данные из последнего состояния (WY).

Я знаю, что мой код отлично работает для того, что я хочу, пока не конкатенация больниц и штатов векторов персонажей.

rankall <- function(outcome, num = "best") {
    data <- read.csv("outcome-of-care-measures.csv", colClasses = "character")
    newframe <- as.data.frame(cbind(data[, 2], data[, 7], data[, 11], data[, 17], data[, 23]), stringsAsFactors = F)
    colnames(newframe) <- c("hospital", "state", "heart attack", "heart failure", "pneumonia")
    splitstates <- split(newframe, newframe$state)

    if (sum(outcome == "heart attack" | outcome == "pneumonia" | outcome == "heart failure") == 0) {
        stop("invalid outcome")
    }
    hospitals <- character()
    states <- character()

    for(i in length(splitstates)) {
        orderoutcome <- order(splitstates[[i]][, eval(outcome)], splitstates[[i]][, "hospital"], na.last = TRUE)
        if(num == "best") {
            num2 <- 1
            rank <-orderoutcome[num2]
        } else if(num == "worst") {
            num2 <- length(orderoutcome)
            rank <- orderoutcome[num2]
        } else {
            rank <- orderoutcome[num] 
        }
        result <- splitstates[[i]][rank, "hospital"]
        hospitals <- c(hospitals, result)
        states <- c(states, splitstates[[i]][1, "state"])
    }
    return <- data.frame(hospitals, states)
    print(return)
}

Ожидается: фрейм данных со строкой для каждого состояния

Факт: кадр данных с одной строкой, соответствующей последнему состоянию (WY)

1 Ответ

0 голосов
/ 01 июня 2019

Подумайте о перефакторинге вашего кода, чтобы избежать избыточности при построении фрейма данных, растущих векторов в цикле и необходимости учета повторяющихся элементов.

Вместо цикла for используйте метод apply family, by, объектно-ориентированную оболочку для tapply.Это похоже на split + lapply (или в вашем случае split + for) для построения окончательного фрейма данных ранжированных больниц во всех штатах.

rankall <- function(outcome, num = "best") {
    if !(outcome %in% c("heart attack", "pneumonia", "heart failure")) {
        stop("invalid outcome")
    }

    data <- read.csv("outcome-of-care-measures.csv", colClasses = "character")
    newframe <- setNames(data[, c(2,7,11,17,23)],
                         c("hospital", "state", "heart attack", "heart failure", "pneumonia"))

    # ORDER ENTIRE DATA FRAME BY STATE, OUTCOME, AND HOSPITAL
    newframe <- with(newframe, newframe[order(state, df[[outcome]], hospital),]
    row.names(newframe) <- NULL

    # BUILD LIST OF 50 DFs FOR EACH STATE SUBSET
    df_list <- by(newframe, newframe$state, function(sub) {
        # CONDITIONALLY ASSIGN ROW SLICE
        if(num == "best") {
            df <- head(sub, 1)
        } else if(num == "worst") {
            df <- tail(sub, 1)
        } else {
            df <- sub[num,] 
        }

        return(df[c("hospital", "state")])                
    })

    final_df <- do.call(rbind, unname(df_list))
    row.names(final_df) <- NULL

    return(final_df)
}

Rextester demo (со случайными, посеянными данными для 5 штатов)

...