Группировать по и только первая строка должна иметь значение во фрейме данных

#r

#r

Вопрос:

У меня есть фрейм данных :

 
df <- data.frame (f1  = c("A1000", "A1000","A1000", "A1000","A1000"),
                   f2 = c("1200", "1200","1200", "1300","1300"),
                  f3 = c("1300", "1400","1500", "1000","2000"),
                  f4 =c("M100","M100","M100","B2300","B2300"),
                  f5=c("D100","D100","D100","G4500","G4500")
)
 

Я хотел бы переформатировать его следующим выводом
Если значение в f1, f2 одинаковы, то значение в f4 и f5 должно отображаться только в первой строке. Остальные значения f4 и f5 должны стать пустыми.

 f1  f2 f3 f4 f5  
A1000 1200 1300 M100 D100  
A1000 1200 1400  
A1000 1200 1500  
A1000 1300 1000 B2300 G4500   
A1000 1300 1000  
 

Любая помощь приветствуется.

Ответ №1:

Простой dplyr ответ

 df %>% group_by(f1, f2) %>% 
  mutate(f4 = ifelse(row_number() != 1, NA, f4),
         f5 = ifelse(row_number() != 1, NA, f5))

# A tibble: 5 x 5
# Groups:   f1, f2 [2]
  f1    f2    f3    f4    f5   
  <chr> <chr> <chr> <chr> <chr>
1 A1000 1200  1300  M100  D100 
2 A1000 1200  1400  NA    NA   
3 A1000 1200  1500  NA    NA   
4 A1000 1300  1000  B2300 G4500
5 A1000 1300  2000  NA    NA
 

Ответ №2:

Это должно сработать, это немного сложное решение, но в основном я использую paste и duplicated для поиска первого экземпляра каждой f1 пары f2 .

Я использовал NA , но вы можете поменять это на "" в каждом ifelse , если вам нужны пустые символы

 df <- data.frame (f1  = c("A1000", "A1000","A1000", "A1000","A1000"),
                  f2 = c("1200", "1200","1200", "1300","1300"),
                  f3 = c("1300", "1400","1500", "1000","2000"),
                  f4 =c("M100","M100","M100","B2300","B2300"),
                  f5=c("D100","D100","D100","G4500","G4500")
)

df$f4 <- ifelse(!duplicated(paste(df$f1,df$f2)), df$f4,NA)
df$f5 <- ifelse(!duplicated(paste(df$f1,df$f2)), df$f5,NA)
 

вывод:

      f1   f2   f3    f4    f5
1 A1000 1200 1300  M100  D100
2 A1000 1200 1400  <NA>  <NA>
3 A1000 1200 1500  <NA>  <NA>
4 A1000 1300 1000 B2300 G4500
5 A1000 1300 2000  <NA>  <NA>
 

Комментарии:

1. Если вам нужно обработать больше столбцов, вы можете обернуть ifelse оператор в apply функцию. например df[,c('f4','f5')] <- apply(df[,c('f4','f5')],2, function(i) ifelse(!duplicated(paste(df$f1,df$f2)), i,NA) )

Ответ №3:

С Base R ,

  group <- paste0(df$f1,df$f2)
    df[setdiff(1:nrow(df),match(unique(group),group)),c("f4","f5")] <- NA
    
    df
 

дает,

      f1   f2   f3    f4    f5
1 A1000 1200 1300  M100  D100
2 A1000 1200 1400  <NA>  <NA>
3 A1000 1200 1500  <NA>  <NA>
4 A1000 1300 1000 B2300 G4500
5 A1000 1300 2000  <NA>  <NA>
>