2 votes

R - changer le contenu de la colonne avec fonction en nouveau contenu

Mon problème est le suivant : j'ai un cadre de données avec une colonne contenant des noms d'espèces comme ceci :

  1. Genre1 espèce1
  2. Genre1 espèce2
  3. Genus2 espèces3

Et je veux simplement couper les noms de genre comme ceci :

  1. G. espèces1
  2. G. espèces2
  3. G. espèces3

Mon problème n'est pas la manupilation des chaînes. Je n'arrive pas à comprendre comment utiliser simplement ma fonction qui ressemble à ça :

truncateGenusName <- function(x){
  genus <- str_sub(x, 1, 1) 
  posOfSpace <- str_locate(x, " ")[1] 
  epitheton <- str_sub(x, posOfSpace, str_length(x)) 
  paste0(genus, '. ', epitheton)
}

J'essayais d'appeler la fonction comme ceci :
mutate(data, species = replace (species, TRUE, truncateGenusName(species)))

Le problème avec cet appel est que ce n'est pas une seule chaîne de caractères qui est transmise à la fonction, mais une liste.

Je suppose que mon approche est bien trop compliquée. Quelqu'un a peut-être un raccourci ?

1voto

iamericfletcher Points 2414

Voici une solution utilisant dplyr , tidyr y stringr .

separate de la tidyr est utilisé pour transformer le names en deux nouvelles colonnes genus y species .

str_trunc de la stringr tronque les chaînes de caractères dans le fichier genus colonne. Notez que la valeur par défaut est d'appliquer trois ellipses indiquant que la chaîne a été tronquée. Utilisation de ellipsis = "." remplace cette valeur par défaut pour ne montrer qu'une seule ellipse.

paste a une valeur par défaut sep = " " Il est donc préférable à paste0 à mon avis.

library(tibble) # Used to create a reproducible example. 
library(dplyr)
library(tidyr)
library(stringr)

# create a reproducible example dataset using the tibble package. 

df <- tibble(
  names = c("Genus1 species1",
            "Genus1 species2",
            "Genus1 species3")
)

# code to format the names column. 

df %>% 
  separate(names, c("genus", "species"), sep = " ") %>% 
  mutate(genus = str_trunc(genus, 2, ellipsis = ".")) %>% 
  mutate(
    genus_species = paste(genus, species)
  ) %>% 
  rename(names = genus_species) %>%
  select(names)

# output table

#> # A tibble: 3 x 1
#>   names      
#>   <chr>      
#> 1 G. species1
#> 2 G. species2
#> 3 G. species3

Créé le 2020-11-19 par le paquet reprex (v0.3.0)

Table originale :

#> # A tibble: 3 x 1
#>   names          
#>   <chr>          
#> 1 Genus1 species1
#> 2 Genus1 species2
#> 3 Genus1 species3

0voto

Dunois Points 1634

Une simple ligne simple en base R :

dat <- read.table(text = "
    Genus1 species1
    Genus1 species2
    Genus2 species3
")

dat$V3 <- paste0(gsub("(?<=^.{1}).*", "", dat$V1, perl = TRUE), ". ", dat$V2)

dat

#       V1       V2          V3
# 1 Genus1 species1 G. species1
# 2 Genus1 species2 G. species2
# 3 Genus2 species3 G. species3

Puisque j'avais mal interprété l'OP, une nouvelle solution en une ligne (toujours en base R) :

dat <- read.table(text = "
    Genus1 species1
    Genus1 species2
    Genus2 species3
")

dat$V3 <- paste0(dat$V1, " ", dat$V2)
dat <- dat[, 3, drop = FALSE]
dat

#                V3
# 1 Genus1 species1
# 2 Genus1 species2
# 3 Genus2 species3

#One-liner below:
dat$V3 <- gsub("(?<=^.{1})[A-Za-z0-9]+(?= )", ".", dat$V3, perl = TRUE)

dat
#            V3
# 1 G. species1
# 2 G. species2
# 3 G. species3

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X