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
dputou 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é.