4
votes

Concaténer conditionnellement la chaîne sur plusieurs lignes

J'ai extrait plusieurs tableaux d'un PDF qui contient des chaînes sur plusieurs lignes. J'ai utilisé la fonction extract_table () du package tabulizer, le seul problème étant que les chaînes sont importées sous forme de lignes séparées.

par exemple

  action description
1      1       a b c
2      2         a b
3      3     a b c d
4      4         a b

Je voudrais concaténer les des chaînes pour qu'elles apparaissent comme le même élément tel que:

action <- c(1, NA, NA, 2, NA, 3, NA, NA, NA, 4, NA)

description <- c("a", "b", "c", "a", "b", "a", "b", "c", "d", "a", "b")

data.frame(action, description)

       action description
1       1           a
2      NA           b
3      NA           c
4       2           a
5      NA           b
6       3           a
7      NA           b
8      NA           c
9      NA           d
10      4           a
11     NA           b

J'espère que cela a du sens, apprécions toute aide!


0 commentaires

4 Réponses :


0
votes

Vous pouvez utiliser les packages zoo et dplyr comme ceci

library(zoo)
library(dplyr)
action <- c(1, NA, NA, 2, NA, 3, NA, NA, NA, 4, NA)
description <- c("a", "b", "c", "a", "b", "a", "b", "c", "d", "a", "b")
df = data.frame(action, description)
df$action = na.locf(df$action)
df = 
    df %>% 
    group_by(action) %>% 
    summarise(description = paste(description, collapse = ' '))


0 commentaires

3
votes

tidyverse serait de remplir la colonne action avec la valeur non-NA précédente puis group_by Action et collez la description ensemble.

library(tidyverse)

df %>%
 fill(action) %>%
 group_by(action) %>%
 summarise(description = paste(description, collapse = " "))


#  action description
#   <dbl> <chr>      
#1     1. a b c      
#2     2. a b        
#3     3. a b c d    
#4     4. a b        


0 commentaires

1
votes

Une option base R

cumsum(!is.na(dat$action)))
#[1] 1 1 1 2 2 3 3 3 3 4 4

Pour que aggregate fonctionne, nous devons changer action en quoi est retourné par cumsum (! is.na (dat $ action))) , c'est-à-dire

dat <- data.frame(action, description)
aggregate(
  description ~ action,
  transform(dat, action = cumsum(!is.na(dat$action))),
  FUN = paste,
  ... = collapse = " "
)
#  action description
#1      1       a b c
#2      2         a b
#3      3     a b c d
#4      4         a b


0 commentaires

1
votes

Voici une option avec data.table

df1 <- data.frame(action, description)

Ou en utilisant na.locf de zoo

library(zoo)
setDT(df1)[, .(description = paste(description, collapse = ' ')),
              .(action = na.locf(action))]

données

library(data.table)
setDT(df1)[, .(description = paste(description, collapse = ' ')), 
                  .(action = cumsum(!is.na(action)))]
#   action description
#1:      1       a b c
#2:      2         a b
#3:      3     a b c d
#4:      4         a b


0 commentaires