Добавить строки в группу в 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)