Повторение строк на основе общего количества, указанного в соответствующих столбцах - PullRequest
0 голосов
/ 29 августа 2018

Как повторить строки по количеству, указанному в соответствующих столбцах (с учетом нескольких столбцов) в R?

data <- data.frame(
 city=c("A","B","C","D","E","F","G"),
 score=c(83,94,1,21,2,3,0),
 J=c(2,0,1,0,3,0,0),
 K=c(0,2,0,3,0,1,0),
 L=c(1,1,0,4,0,0,0))
data

Исходный фрейм данных :

enter image description here

Требуемый фрейм данных :

enter image description here

С учетом количества столбцов, P.S. Город D, который повторяется 4 раза, из которых 3 строки в столбце k имеют счет 1, а 4 строки в столбце L имеют счет 1 относительно города D.

Ответы [ 3 ]

0 голосов
/ 29 августа 2018

Обратите внимание, что в ожидаемых результатах на основе предоставленных вами образцов данных есть некоторые ошибки (см. Комментарий @markus).

Вот опция tidyverse с использованием splitstackshape::cSplit

library(splitstackshape)   
library(tidyverse)
data %>%
    rowwise() %>%
    mutate_at(vars(starts_with("number")), funs(toString(rep(1, .)))) %>%
    group_by(city) %>%
    cSplit(grep("^number", names(data), value = T), direction = "long") %>%
    filter_at(vars(starts_with("number")), any_vars(!is.na(.))) %>%
    replace(., is.na(.), 0)
#   city score number number2 number3
#1     A    83      1       0       1
#2     A    83      1       0       0
#3     B    94      0       1       1
#4     B    94      0       1       0
#5     C     1      1       0       0
#6     D    21      0       1       1
#7     D    21      0       1       1
#8     D    21      0       1       1
#9     D    21      0       0       1
#10    E     2      1       0       0
#11    E     2      1       0       0
#12    E     2      1       0       0
#13    F     3      0       1       0

Объяснение: Идея состоит в том, чтобы заменить каждую запись number на vector числа 1 s, соответствующего ее значению, которое мы, в свою очередь, преобразуем в вектор character, разделенный запятыми, на toString. Затем мы используем splitstackshape::cSplit, чтобы разбить эти записи на несколько строк, удалить все- NA строки и заменить NA s на 0 s.

0 голосов
/ 29 августа 2018

Другое решение для data.table:

library(data.table)
setDT(data)
data[, lapply(.SD, function(x){
    g <- pmax(max(unlist(.SD)), 1)
    rep(1:0, c(x, g - x)) }), by = .(city, score)]

#     city score number number2 number3
#  1:    A    83      1       0       1
#  2:    A    83      1       0       0
#  3:    B    94      0       1       1
#  4:    B    94      0       1       0
#  5:    C     1      1       0       0
#  6:    D    21      0       1       1
#  7:    D    21      0       1       1
#  8:    D    21      0       1       1
#  9:    D    21      0       0       1
# 10:    E     2      1       0       0
# 11:    E     2      1       0       0
# 12:    E     2      1       0       0
# 13:    F     3      0       1       0
# 14:    G     0      0       0       0

Строки со всеми числами, равными нулю, обрабатываются правильно. Замените g <- pmax(max(unlist(.SD)), 1) на g <- max(unlist(.SD)), если вы не хотите такие строки:

data[, lapply(.SD, function(x){
    g <- max(unlist(.SD))
    rep(1:0, c(x, g - x)) }), by = .(city, score)]
0 голосов
/ 29 августа 2018

data.table решение:

данные: (убедитесь, что у вас нет факторов stringsAsFactors = F)

data <- data.frame(
    city=c("A","B","C","D","E","F","G"),
    score=c(83,94,1,21,2,3,0),
    number=c(2,0,1,0,3,0,0),
    number2=c(0,2,0,3,0,1,0),
    number3=c(1,1,0,4,0,0,0),stringsAsFactors = F)

код: (давайте возьмем функцию fun1, которая сделает всю работу за нас)

data.table::setDT(data)

fun1 <- function(x) {
    transpose(
        transpose(
            lapply(x, function(u) if(u != 0) rep(1,u) else 0), fill = 0
        )
    )
}

data[, structure(fun1(.SD), .Names = names(.SD)), by = c("city","score")]

результат:

 #   city score number number2 number3
 #1:    A    83      1       0       1
 #2:    A    83      1       0       0
 #3:    B    94      0       1       1
 #4:    B    94      0       1       0
 #5:    C     1      1       0       0
 #6:    D    21      0       1       1
 #7:    D    21      0       1       1
 #8:    D    21      0       1       1
 #9:    D    21      0       0       1
#10:    E     2      1       0       0
#11:    E     2      1       0       0
#12:    E     2      1       0       0
#13:    F     3      0       1       0
#14:    G     0      0       0       0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...