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?
3 Réponses :
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
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) })
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"))
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
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é.