2014-05-05 1 views
0

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

Я знаю, как повторять строки, используя этот код:

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) 
+0

Функция ddply в plyr (или ее новой версии dplyr), вероятно, поможет здесь. Я думаю, что это должно решить вашу проблему: https://stackoverflow.com/questions/21096754/ddply-to-split-and-add-rows-to-each-group – SprengMeister

+0

Я бы прошел через каждого человека, используя 'by' или что-то подобный, и работа оттуда. Если вы предоставите небольшой пример, который я копирую/вставляю в R, я могу посмотреть. –

+0

@ RomanLuštrik большое вам спасибо - здесь вы идете: noms <-as.character (c ('mary', 'mary', 'mary', 'mary', 'john', 'john', 'john', ' («яблоко», «виноград», «апельсин», «яблоко», «бананы», «яблоко», «яблоко», «яблоко», «киви», «оранжевое», «яблочное», «ягодное», «оранжевое»)) df <-data.frame (noms, fruits) – user2363642

ответ

1

Вы по праву трек с 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 
+0

Блестящий! это намного лучше, чем моя попытка выше. Спасибо!!! :) – user2363642

0

с использованием коды из предыдущего вопроса; ddply to split and add rows to each group

вот ответ

первым, создать переменную числа в ДФ

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) 

 Смежные вопросы

  • Нет связанных вопросов^_^