2017-04-16 3 views
1

Ich habe ein Datenframe p1. Ich würde gerne nach Spalte a transponieren. Suchen Sie das Minimum jeder Zeile und geben Sie den Spaltennamen mit dem Mindestwert zurück.Transponieren von Datenrahmen nach Spalte, Suche nach Spaltenminimum und Rückgabe Index

a=c(0,1,2,3,4,0,1,2,3,4) 
b=c(10,20,30,40,50,9,8,7,6,5) 
p1=data.frame(a,b) 
p1 


> p1 
    a b 
1 0 10 
2 1 20 
3 2 30 
4 3 40 
5 4 50 
6 0 9 
7 1 8 
8 2 7 
9 3 6 
10 4 5 

Die endgültige erforderliche Antwort

0 1 2 3 4 row_minimum column_index_of_minimum 
10 20 30 40 50 10    0 
9 8 7 6 5 5    4 

Antwort

2

ich viele Dinge verwendet, aber die Haupt war ave(p1$a, p1$a, FUN = seq_along) die mir die b in Gruppen auf der Grundlage der Anzahl, wie oft auftrennen sie mit a verbunden waren

myans = setNames(data.frame(do.call(rbind, lapply(split(p1, ave(p1$a, p1$a, FUN = seq_along)), 
      function(x) x[,2]))), nm = rbind(p1$a[ave(p1$a, p1$a, FUN = seq_along) == 1])) 
minimum = apply(myans, 1, min) 
index = colnames(myans)[apply(myans, 1, which.min)] 
myans$min = minimum 
myans$index = index 
myans 
# 0 1 2 3 4 min index 
#1 10 20 30 40 50 10  0 
#2 9 8 7 6 5 5  4 
1

Erwägen Sie, eine laufende Gruppenzählung gefolgt von einem Aggregat zu verwenden und umzuformen:

# RUNNING GROUP COUNT 
p1$grpcnt <- sapply(seq(nrow(p1)), function(i) sum(p1[1:i, c("a")]==p1$a[[i]])) 

# MINIMUM OF B BY GROUP COUNT MERGING TO RETRIEVE A VALUE 
aggdf <- setNames(merge(aggregate(b~grpcnt, p1, FUN=min),p1,by="b")[c("grpcnt.x","b","a")], 
        c("grpcnt", "row_minimum", "column_index_of_minimum")) 

# RESHAPE/TRANSPOSE LONG TO WIDE 
reshapedf <- setNames(reshape(p1, timevar=c("a"), idvar=c("grpcnt"), direction="wide"), 
         c("grpcnt", paste(unique(p1$a)))) 
# FINAL MERGE 
finaldf <- merge(reshapedf, aggdf, by="grpcnt")[-1] 
finaldf 

# 0 1 2 3 4 row_minimum column_index_of_minimum 
# 1 10 20 30 40 50   10      0 
# 2 9 8 7 6 5   5      4 
Verwandte Themen