2016-07-27 1 views
3

Je veux calculer rowMeans d'une plage de colonnes mais je ne peux pas donner la valeur codée en dur pour les colnames (par exemple c (C1, C3)) ou gamme (ex: C1: C3) car les noms et la portée sont variables. Mon df ressemble:Calculer rowMeans sur une plage de colonne (numéro de variable)

> df 
    chr name age MGW.1 MGW.2 MGW.3 HEL.1 HEL.2 HEL.3 
1 123 abc 12 10.00 19 18.00 12 13.00 -14 
2 234 bvf 24 -13.29 13 -3.02 12 -0.12 24 
3 376 bxc 17 -6.95 10 -18.00 15 4.00 -4 

Ceci est juste un échantillon, en réalité, j'ai colonnes allant dans MGW.1 ... MGW.196 et ainsi. Ici Au lieu de donner les colnames exactes ou une plage exacte, je veux passer l'initiale de colnames et vouloir obtenir la moyenne de toutes les colonnes ayant ces initiales. Quelque chose comme: MGW=rowMeans(df[,MGW.*]), HEL=rowMeans(df[,HEL.*])

donc ma sortie finale devrait ressembler à:

> df 
     chr name age MGW  Hel 
    1 123 abc 12 10.00 19 
    2 234 bvf 24 13.29 13 
    3 376 bxc 17 -6.95 10 

Je sais que ces valeurs ne sont pas correctes, mais il est juste pour vous donner et idée. Deuxièmement, je veux supprimer toutes les lignes de la trame de données qui contient NA dans la ligne entière à l'exception des 3 premières valeurs.

Voici le dput par exemple exemple:

> dput(df) 
structure(list(chr = c(123L, 234L, 376L), name = structure(1:3, .Label = c("abc", 
"bvf", "bxc"), class = "factor"), age = c(12L, 24L, 17L), MGW.1 = c(10, 
-13.29, -6.95), MGW.2 = c(19L, 13L, 10L), MGW.3 = c(18, -3.02, 
-18), HEL.1 = c(12L, 12L, 15L), HEL.2 = c(13, -0.12, 4), HEL.3 = c(-14L, 
24L, -4L)), .Names = c("chr", "name", "age", "MGW.1", "MGW.2", 
"MGW.3", "HEL.1", "HEL.2", "HEL.3"), class = "data.frame", row.names = c(NA, 
-3L)) 
+0

J'ai posé une question connexe hier et les réponses pourraient vous aider t. Voici le lien http: // stackoverflow.com/questions/38594808/better-way-d'addition-data-frame-columns-by-reference-to-indeces – Warner

+0

@Warner Comme je l'ai mentionné dans ma question, je ne peux pas explicitement mentionner les colnames ou les index, car ils sont variables , parfois il y aura 196 colonnes pour lesquelles je veux un rowMean et parfois il y en aura 198 ou plus. – Newbie

+0

Vous pouvez sous-ensemble 'df' avec un vecteur" logique "de positions où' names (df) ''? StartsWith' '" MGW "' etc. Aussi, voyez '' complete.cases' pour trouver les lignes qui contiennent seulement ' NA' (après avoir déduit toutes les colonnes sauf les trois premières). –

Répondre

2

est ici une idée la réalisation de votre sortie désirée sans hardcoding noms de variables:

library(dplyr) 
library(tidyr) 

df %>% 
    # remove rows where all values are NA except the first 3 columns 
    filter(rowSums(is.na(.[4:length(.)])) != length(.) - 3) %>% 
    # gather the data in a tidy format 
    gather(key, value, -(chr:age)) %>% 
    # separate the key column into label and num allowing 
    # to regroup by variables without hardcoding them 
    separate(key, into = c("label", "num")) %>% 
    group_by(chr, name, age, label) %>% 
    # calculate the mean 
    summarise(mean = mean(value, na.rm = TRUE)) %>% 
    spread(label, mean) 

Je pris la liberté de modifier vos données initiales pour montrer comment la logique cadrerait des cas particuliers. Par exemple, ici nous avons une ligne (# 4) où toutes les valeurs sauf les 3 premières colonnes sont NA s (selon vos besoins, cette ligne devrait être supprimée) et une où il y a un mélange de NA s et de valeurs (# 5). Dans ce cas, je suppose que nous aimerions avoir un résultat pour MGW car il y a une valeur à MGW.1:

# chr name age MGW.1 MGW.2 MGW.3 HEL.1 HEL.2 HEL.3 
#1 123 abc 12 10.00 19 18.00 12 13.00 -14 
#2 234 bvf 24 -13.29 13 -3.02 12 -0.12 24 
#3 376 bxc 17 -6.95 10 -18.00 15 4.00 -4 
#4 999 zzz 21  NA NA  NA NA NA NA 
#5 888 aaa 12 10.00 NA  NA NA NA NA 

Ce qui donne:

#Source: local data frame [4 x 5] 
#Groups: chr, name, age [4] 
# 
# chr name age  HEL  MGW 
#* <int> <fctr> <int>  <dbl>  <dbl> 
#1 123 abc 12 3.666667 15.666667 
#2 234 bvf 24 11.960000 -1.103333 
#3 376 bxc 17 5.000000 -4.983333 
#4 888 aaa 12  NaN 10.000000 

données

df <- structure(list(chr = c(123L, 234L, 376L, 999L, 888L), name = structure(c(2L, 
3L, 4L, 5L, 1L), .Label = c("aaa", "abc", "bvf", "bxc", "zzz" 
), class = "factor"), age = c(12L, 24L, 17L, 21L, 12L), MGW.1 = c(10, 
-13.29, -6.95, NA, 10), MGW.2 = c(19L, 13L, 10L, NA, NA), MGW.3 = c(18, 
-3.02, -18, NA, NA), HEL.1 = c(12L, 12L, 15L, NA, NA), HEL.2 = c(13, 
-0.12, 4, NA, NA), HEL.3 = c(-14L, 24L, -4L, NA, NA)), .Names = c("chr", 
"name", "age", "MGW.1", "MGW.2", "MGW.3", "HEL.1", "HEL.2", "HEL.3" 
), class = "data.frame", row.names = c("1", "2", "3", "4", "5")) 
2

Tout d'abord

Je pense que vous êtes à la recherche pour que cela se dire de lignes:

df$mean.Hel <- rowMeans(df[, grep("^HEL.", names(df))]) 

et de supprimer les colonnes après:

df[, grep("^HEL.", names(df))] <- NULL 

En second lieu

Pour supprimer des lignes qui ont seulement NA après les trois premiers éléments.

rows.delete <- which(rowSums(!is.na(df)[,4:ncol(df)]) == 0) 
df <- df[!(1:nrow(df) %in% rows.delete),] 
+0

Cela ajoutera une nouvelle colonnes Hel.mean Je veux également supprimer la colonne individuelle de df, s'il vous plaît se référer à ma sortie désirée mentionnée ci-dessus. – Newbie

+0

Ajout d'une ligne pour supprimer les colonnes. – snoram

+0

Que voulez-vous dire par Deuxièmement ... ?? .. Je pense que vous dites que répéter pour MGW et ainsi de suite toutes les colonnes que vous voulez, non? – Newbie