в R разделить столбец в кадре данных с разной длиной

Я пытаюсь разделить столбец «Награды» в фрейме данных, но при разделении столбец возвращает разное количество результатов, как мне связать его обратно с исходным фреймом данных:

ОБРАЗЕЦ ДФ:

        Name   Value     Awards
1       A1      NA      3 wins.
2       A2      1000    NA
3       A3      NA      2 wins.
4       A4      1999    1 win
5       A5      8178569 5 wins & 4 nominations.

ОЖИДАЕМЫЙ РЕЗУЛЬТАТ:

        Name   Value     Awards                 AwardsNum  Cat
1       A1      NA      3 wins.                 3          A
2       A2      1000    NA                      NA         NA
3       A3      NA      2 wins.                 2          A
4       A4      1999    1 win                   1          A
5       A5      8178569 5 wins & 4 nominations. 9          C

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

У меня есть следующее:

  strsplit(DF$Awards," ")
  cbind(DF,strsplit(DF$Awards," ") 

Error in data.frame(c("3", "wins."), "N/A", c("2", "wins."), c("1", "win." : 
arguments imply differing number of rows: 2, 1, 5

ОБНОВЛЕНИЕ: КАТЕГОРИИ ‹--- для NA и без наград и номинаций - A ‹--- от 1 до 5 Категория B ‹-- иначе C

I need to play around between B and C since I need to make sure that they are not more than 5:1 ratio between B and C

person E B    schedule 09.10.2016    source источник
comment
Что определяет различные категории? Например, как узнать, что одна строка должна относиться к категории A, а не к категории C?   -  person jdobres    schedule 09.10.2016


Ответы (2)


Решение состоит в том, чтобы использовать регулярное выражение для сопоставления всех чисел. Затем вы можете суммировать их и назначать категории.

library(stringr)

df_new <- sapply(DF$Awards, function(x){
    # get all numbers
    nums <- unlist(str_match_all(x, "[0-9]+"))
    # calculate sum
    AwardsNum <- sum(as.numeric(nums))
    # assign category basing on sum
    if (is.na(AwardsNum)){
        Cat <- NA
    }else if(AwardsNum == 0){
        Cat <- "A"
    }else if(AwardsNum < 5){
        Cat <- "B"
    }else{
        Cat <- "C"
    }
    return(c(AwardsNum, Cat))
})

# create new rows in df
DF$AwardsNum <- as.numeric(df_new[1, ])
DF$Cat <- df_new[2, ]
person Istrel    schedule 09.10.2016

Я только что понял, что @Istrel уже опубликовал ответ, пока я работал над этим вопросом. Я все равно опубликую свой, так как он немного отличается.

df <- data.frame(
    Name = c("A1", "A2", "A3", "A4", "A5"),
    Value = c(NA, 1000, NA, 1999, 8178569),
    Awards = c("3 wins", NA, "2 wins", "1 win", "5 wins & 4 nomiations")
)

library(magrittr)
n.awards <- sapply(df$Awards, function(x){
    ifelse(is.na(x), 0,{
        x %>% as.character %>%
            strsplit("[^0-9]+") %>%
            unlist %>%
            as.numeric %>%
            sum
    })
})
brks <- c(-0.1,0.9,4.9, 100)
cc <- cut(n.awards,brks)
cat <- c("A", "B", "C")
df.final <- cbind(df, AwardsNum = n.awards, Cat = cat[cc])

Используя cut, вы можете группировать векторы без использования нескольких операторов if.

person parksw3    schedule 09.10.2016
comment
!parksw3 и @lstrel, оба ваших предложения великолепны... и быстрее, чем aloop - person E B; 13.10.2016
comment
@lstrel, единственное, что я пытаюсь выяснить, это как собрать его вместе с исходным фреймом данных ... я думал, что смогу сделать rbind, но не уверен, как я могу быть уверен, что присоединю его к исходной строке - person E B; 13.10.2016