2016-07-27 24 views
3

Ich möchte rowMeans eines Spaltenbereichs berechnen, aber ich kann den hartcodierten Wert für colnames (zB c (C1, C3)) oder Bereich (zB C1: C3) als beide Namen und Bereich sind variabel. Mein df wie folgt aussieht:Berechne rowMeans für einen Spaltenbereich (Variablennummer)

> 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 

Dies ist nur ein Beispiel ist, in Wirklichkeit habe ich Spalten bis hin in MGW.1 ... MGW.196 und so. Anstatt die genauen Spaltennamen oder einen exakten Bereich anzugeben, möchte ich die Initialen von Spaltennamen übergeben und möchte den Durchschnitt aller Spalten mit diesen Initialen erhalten. Etwas wie: MGW=rowMeans(df[,MGW.*]), HEL=rowMeans(df[,HEL.*])

So sollte meine letzte Ausgabe wie folgt aussehen:

> 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 

Ich weiß, dass diese Werte nicht korrekt sind, aber es ist nur Sie und Idee zu geben. Zweitens möchte ich alle diese Zeilen aus dem Datenrahmen entfernen, die NA in der gesamten Zeile mit Ausnahme der ersten 3 Werte enthält. Hier

ist die dput für Probe Beispiel:

> 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

Ich habe gestern eine verwandte Frage gestellt und die Antworten könnten Ihnen helfen t. Hier ist der Link http: // Stackoverflow.com/questions/38594808/better-way-of-adding-data-frame-columns-by-refering-to-indeces – Warner

+0

@Warner Wie ich in meiner Frage erwähnt habe, kann ich die colnames oder Indizes nicht explizit erwähnen, weil sie variabel sind Manchmal wird es 196 Spalten geben, für die ich eine Zeile möchte und manchmal wird es 198 oder so sein. – Newbie

+0

Sie können Teilmenge 'df' mit einem" logischen "Vektor von Positionen angeben, wobei' Namen (df) ''? StartsWith' '" MGW "usw. usw. Außerdem finden Sie'? Complete.cases', um Zeilen zu finden, die nur 'enthalten NA' (nach Unterteilung aller bis auf die ersten drei Spalten). –

Antwort

2

Hier ist eine Idee, um Ihre gewünschte Ausgabe zu erzielen, ohne hartzucodieren Variablennamen:

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) 

Ich erlaube mich Ihre ersten Daten zu ändern, zu zeigen, wie die Logik besondere Fälle passen würde. Zum Beispiel haben wir hier eine Zeile (# 4), wo alle Werte außer den ersten 3 Spalten NA s sind (nach Ihren Anforderungen sollte diese Zeile entfernt werden) und eine wo es eine Mischung aus NA s und Werten (# 5). In diesem Fall wird davon ausgegangen, ich, dass wir ein Ergebnis haben für MGW möchten, da es einen Wert, bei MGW.1 ist:

# 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 

Welche gibt:

#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 

Daten

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

Zum einen

Ich glaube, Sie für diese suchen Zeilen erhalten bedeuten:

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

Und das löschen Spalten danach:

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

Zweitens

Zeilen zu löschen, die nur NA nach den ersten drei Elemente haben.

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

Dies wird eine neue Spalten anhängen Hel.Mean Ich möchte auch die einzelne Spalte aus df löschen, bitte beziehen Sie sich auf meine gewünschte Ausgabe oben. – Newbie

+0

Eine Zeile zum Löschen der Spalten hinzugefügt. – snoram

+0

Was meinst du mit Zweitem ... ?? .. Ich denke, du sagst, dass du es für MGW wiederholst und so weiter mit allen Spalten, die du willst, oder? – Newbie