Добавить строки в группу в df

У меня есть data.frame с различным количеством строк на человека. Если у человека меньше 4 рядов, я бы хотел дать ему 4 ряда. Я хотел бы, чтобы дополнительные строки были копией последней строки на человека, например, Том ниже.

Я знаю, как повторять строки с помощью этого кода:

dff <- df[rep(1:nrow(df), each=4), ] 

Но проблема здесь в том, что у меня нет аргументов только для репликации строк для идентификаторов, которые встречаются менее 4 раз.

Я пробовал это:

dff <- ifelse(length(df$noms < 4), 
              df[rep(1:nrow(df), each=4), ], df) ##doesn't work

Я думаю, что я мог бы использовать do.call(rbind, ...) но опять же, мне не удается интегрировать мой аргумент в код.

Вот что я пробовал:

df <- ifelse(length(df$noms<4), 
             do.call(rbind, by(df, df$noms, rbind, 1:nrow(df))), 
             df) ## doesn't work

А также мне не удалось привести аргумент в пользу того, сколько повторений нужно сделать.

   noms fruits apple orange kiwi all_comb comb
1  mary  apple     1      0    0        1    1
2  mary  grape     0      0    0        0    1
3  mary orange     0      1    0        0    1
4  mary  apple     1      0    0        1    1
5  john banana     0      0    0        0    1
6  john  apple     1      0    0        1    1
7  john  apple     1      0    0        1    1
8  john  apple     1      0    0        1    1
9  lucy   kiwi     0      0    1        0    1
10 lucy orange     0      1    0        0    1
11 lucy  apple     1      0    0        1    1
12 lucy  berry     0      0    0        0    1
13  tom orange     0      1    0        0    1

Желаемый вывод

   noms fruits apple orange kiwi all_comb comb
1  mary  apple     1      0    0        1    1
2  mary  grape     0      0    0        0    1
3  mary orange     0      1    0        0    1
4  mary  apple     1      0    0        1    1
5  john banana     0      0    0        0    1
6  john  apple     1      0    0        1    1
7  john  apple     1      0    0        1    1
8  john  apple     1      0    0        1    1
9  lucy   kiwi     0      0    1        0    1
10 lucy orange     0      1    0        0    1
11 lucy  apple     1      0    0        1    1
12 lucy  berry     0      0    0        0    1
13  tom orange     0      1    0        0    1
14  tom orange     0      1    0        0    1
15  tom orange     0      1    0        0    1
16  tom orange     0      1    0        0    1

Вот некоторые воспроизводимые данные:

noms <- as.character(c('mary', 'mary','mary','mary','john','john','john',
                       'john','lucy','lucy','lucy','lucy', 'tom'))
fruits <- as.character(c('apple','grape','orange','apple','banana',
                         'apple','apple','apple','kiwi','orange',
                         'apple','berry', 'orange'))
df <- data.frame(noms,fruits)

2 ответа

Решение

Вы на правильном пути с ifelse, Попробуйте следующее:

noms <- as.character(c('mary', 'mary','mary','mary','john','john','john',
                       'john','lucy','lucy','lucy','lucy', 'tom'))
fruits <- as.character(c('apple','grape','orange','apple','banana',
                         'apple','apple','apple','kiwi','orange',
                         'apple','berry', 'orange'))
df <- data.frame(noms,fruits)

x <- with(df, ave(rep(1, nrow(df)), noms, FUN = length))
df[rep(rownames(df), ifelse(x >= 4, 1, 4)), ]
#      noms fruits
# 1    mary  apple
# 2    mary  grape
# 3    mary orange
# 4    mary  apple
# 5    john banana
# 6    john  apple
# 7    john  apple
# 8    john  apple
# 9    lucy   kiwi
# 10   lucy orange
# 11   lucy  apple
# 12   lucy  berry
# 13    tom orange
# 13.1  tom orange
# 13.2  tom orange
# 13.3  tom orange

Используя код из предыдущего вопроса; ddply для разделения и добавления строк в каждую группу

вот ответ

во-первых, создайте переменную с именем numbers в df

df$numbers<-ave(df$noms,df$noms, FUN=seq_along)

затем манипулируйте кодом, приведенным в предыдущем ответе:

AddRows <- function(df) {
  new_numbers <- seq(from = min(df$numbers), to = 4)
  new_numbers <- new_numbers[new_numbers != 0]    ##probably don't need this line
  noms <- rep(unique(df$noms), length(new_numbers))

  return(data.frame(df, new_numbers))
}

ddply(df, .(noms), AddRows)
Другие вопросы по тегам