0
votes

Utilisation d'un vecteur comme motif grep

Je suis nouveau dans R. J'essaye de rechercher les colonnes en utilisant grep plusieurs fois dans une boucle d' apply . J'utilise grep pour spécifier quelles lignes sont additionnées en fonction des individuals du vecteur

>head(bcdata_total)
  ID1 ID2
A  5   1
B  4   3 
C  9   5

bcdata est de taille aléatoire et contient des données aléatoires mais contient des colonnes qui ont des individuals dans une partie de la chaîne

 apply(bcdata_clean[,grep(individuals[1,2....n], colnames(bcdata_clean))], 1, sum)

grep(individuals[1],colnames(bcdata_clean)) renvoie un vecteur qui ressemble à [1] 1 2 , une liste des noms de colonnes contenant ID1 . Ce vecteur est utilisé pour sélectionner les colonnes à additionner dans bcdata_clean . Cela devrait se produire n nombre de fois en fonction de la longueur des individuals

Cependant, cela renvoie l'erreur

In grep(individuals, colnames(bcdata)) :
  argument 'pattern' has length > 1 and only the first element will be used

Et aboutit à ce que toutes les colonnes de bcdata soient identiques

Idéalement, les individuals incrémenteraient chaque fois que la fonction est exécutée comme ceci pour chaque itération

>head(bcdata)
  ID1-4 ID1-3 ID2-5
A   3     2    1
B   2     2    3
C   4     5    5

et aboutirait à quelque chose comme ça

individuals <-c("ID1","ID2".....n)
bcdata_total <- sapply(individuals, function(x) {
  apply(bcdata_clean[,grep(individuals, colnames(bcdata_clean))], 1, sum)
})

Mais je ne sais pas comment incrémenter les individuals . Quelle est la meilleure façon de procéder au sein de la fonction?


4 commentaires

Veuillez ajouter des données en utilisant dput ou quelque chose que nous pouvons copier et utiliser. Afficher également la sortie attendue pour les données partagées. Découvrez comment poser une bonne question et comment donner un exemple reproductible .


Ce devrait être grep(x, colnames(bcdata_clean))


Je l'ai modifié pour contenir des exemples de données


@ekoam Ha, merci beaucoup. Cela a en fait beaucoup aidé.


3 Réponses :


0
votes

Vous pouvez utiliser split.default pour fractionner les données sur des colonnes de nom similaire et les additionner par ligne.

df <- structure(list(`ID1-4` = c(3L, 2L, 4L), `ID1-3` = c(2L, 2L, 5L
), `ID2-5` = c(1L, 3L, 5L)), class = "data.frame", row.names = c("A", "B", "C"))

Les données

sapply(split.default(df, sub('-.*', '', names(df))), rowSums, na.rm. = TRUE)

#  ID1 ID2
#A   5   1
#B   4   3
#C   9   5


0 commentaires

0
votes

Passer des individuals comme argument dans la function(x) résolu mon problème

bcdata_total <- sapply(individuals, function(individuals) {
  apply(bcdata_clean[,grep(individuals, colnames(bcdata_clean))], 1, sum)
})


0 commentaires

0
votes

Une option avec tidyverse

df <- df <- structure(list(`ID1-4` = c(3L, 2L, 4L), `ID1-3` = c(2L, 2L, 5L
), `ID2-5` = c(1L, 3L, 5L)), class = "data.frame", row.names = c("A", "B", "C"))

Les données

library(dplyr)
library(tidyr)
library(tibble)
df %>%
    rownames_to_column('rn') %>%
    pivot_longer(cols = -rn, names_to = c(".value", "grp"), names_sep="-") %>%
    group_by(rn) %>% 
    summarise(across(starts_with('ID'), sum, na.rm = TRUE), .groups = 'drop') %>%
    column_to_rownames('rn')
#  ID1 ID2
#A   5   1
#B   4   3
#C   9   5


0 commentaires