2017-04-18 6 views
2

Ich habe in diesem Format eine csv bevölkern:zu schaffen und neue Spalten in einem Datenrahmen basierend auf den Werten von vorhandenen Spalten

Col1_Status Col1_Value Col2_Status Col2_Value Col3_Status Col3__Value 
LOW    5   HIGH   5   LOW   5 
LOW    8   HIGH   8   LOW   8 
HIGH   82   HIGH   8   LOW   7 
HIGH   83   NORMAL  8   LOW   7 
HIGH   82   NORMAL  8   LOW   7 

Ich möchte erstellen Sie einen neuen Datenrahmen mit der hohen und niedrigen als Spalt, zum Beispiel:

Col1_High Col1_Low Col2_High Col2_Low Col3_High Col3_Low 
    82   5  5  NA  NA  5 
    83   8  8  NA  NA  8 
    82   NA  8  NA  NA  7 
    NA   NA  NA  NA  NA  7 
    NA   NA  NA  NA  NA  7 

Was ist der beste Weg, um darüber zu gehen?

Bisher denke ich:

#extract the Status Columns from original file into DataFrame 
    statusDF <- ret[grepl("Status", colnames(ret))] 

    #extract the Value Columns from original file into DataFrame 
    originalValueDF <- ret[grepl("Value", colnames(ret))] 

    #create new columns attribute_high and attribute_low 
    for(i in names(originalValueDF)){ 
    newValueDF <- originalValueDF[[paste(i, 'High', sep = "_")]] 
    newValueDF <- originalValueDF[[paste(i, 'Low', sep = "_")]] 
    } 

#populate both columns based on value in attribute status column 
for(i in names(originalValueDF)){ 
    if (originalValueDF$i == "High"){ 
     temp <- # stuck here 
    } 
    } 

Jeder beraten

+0

'Col3_Low = c (5, 8)' ... wobei 7? Was sind deine Kriterien? – Sotos

+0

Entschuldigung, ich gab nur die ersten zwei Tupel als die gewünschte Ausgabe. Das Kriterium besteht darin, die Statusspalte zu betrachten und sie in eine neue Spalte hoch oder niedrig zu extrahieren. – ukbaz

+0

haben den Ausgabedatenrahmen aktualisiert – ukbaz

Antwort

1

Hier geschätzt wird, ist ein Versuch, mit vielen lapply. Wir erstellen zuerst eine Liste (l1), die die Werte für jeden Status 'Hoch' und 'Niedrig' übernimmt. Die Längen dieser Vektoren sind jedoch unterschiedlich, also müssen wir sie alle gleich ihrem Maximum setzen (in unserem Fall ind). Wir konvertieren die Vektoren in Matrizen mit 2 Spalten (hoch und niedrig) und verwenden do.call mit cbind, um den endgültigen Datenrahmen zu erhalten.

l1 <- lapply(seq(1, ncol(df), by = 2), function(i) list(HIGH = df[i+1][df[i] == 'HIGH'], 
                 LOW = df[i+1][df[i] == 'LOW'])) 
names(l1) <- paste0('Col', seq(length(l1))) 

ind <- max(unlist(lapply(l1, function(i) lengths(i)))) 

do.call(cbind, lapply(lapply(l1, function(i) lapply(i, `length<-`, ind)), function(j) 
        setNames(data.frame(matrix(unlist(j), ncol = 2)), c('High', 'Low')))) 

# Col1.High Col1.Low Col2.High Col2.Low Col3.High Col3.Low 
#1  82  5   5  NA  NA  5 
#2  83  8   8  NA  NA  8 
#3  82  NA   8  NA  NA  7 
#4  NA  NA  NA  NA  NA  7 
#5  NA  NA  NA  NA  NA  7 
+0

groß danke, würde es Ihnen etwas ausmachen, es zu erklären - das scheint ziemlich komplex – ukbaz

0
ret <- read.table(text=" 
Col1_Status Col1_Value Col2_Status Col2_Value Col3_Status Col3__Value 
LOW    5   HIGH   5   LOW   5 
LOW    8   HIGH   8   LOW   8 
HIGH   82   HIGH   8   LOW   7 
HIGH   83   NORMAL  8   LOW   7 
HIGH   82   NORMAL  8   LOW   7 
", header = TRUE, stringsAsFactors = F) 

# fix column headers 
names(ret) <- gsub("(_+)", "_", names(ret)) 

library(stats) 

# extract the column prefixes 
prefixes <- unique(gsub("_.+", "", names(ret))) 
value_names <- names(ret[grepl("_Value", names(ret))]) 
status_names <- names(ret[grepl("_Status", names(ret))]) 

library(stats) 
# get the lwo values - extract the lows, pad with NA's and set the name to _High 
high_values <- sapply(1:length(prefixes), 
         function(i) { 
         result <- ret[which(ret[, status_names][i] == "HIGH"), value_names][[i]] 
         result[(length(result)+1):nrow(ret)+1] <- NA 
         setNames(list(foo = result[1:nrow(ret)]), paste0(prefixes[i], "_High"))}) 

# get the lwo values - extract the lows, pad with NA's and set the name to _Low 
low_values <- sapply(1:length(prefixes), 
         function(i) { 
         result <- ret[which(ret[, status_names][i] == "LOW"), value_names][[i]] 
         result[(length(result)+1):nrow(ret)+1] <- NA 
         setNames(list(foo = result[1:nrow(ret)]), paste0(prefixes[i], "_Low"))}) 

# combine 
output <- cbind(data.frame(low_values), data.frame(high_values)) 

output 

# Col1_Low Col2_Low Col3_Low Col1_High Col2_High Col3_High 
# 1  5  NA  5  82   5  NA 
# 2  8  NA  8  83   8  NA 
# 3  NA  NA  7  82   8  NA 
# 4  NA  NA  7  NA  NA  NA 
# 5  NA  NA  7  NA  NA  NA 
Verwandte Themen