2017-04-18 71 views
2

我在这个格式的CSV:创建并从现有列填充基于价值的数据帧新列

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 

我想创建一个具有高,低栏目,例如一个新的数据帧:

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 

什么是最好的方式去做这件事?

到目前为止,我认为:

#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 
    } 
    } 

任何建议表示赞赏

+0

'Col3_Low = C(5,8)'...其中是7?你的标准是什么? – Sotos

+0

对不起,我只是把前两个元组作为所需的输出。标准是查看状态列并将其提取到高或低的新列中。 – ukbaz

+0

已更新输出数据帧 – ukbaz

回答

1

这里是一个有很多的lapply的尝试。我们首先创建一个列表(l1),其中包含每个“高”和“低”状态的值。但是,这些向量的长度是不同的,所以我们需要将它们全部设置为等于它们的最大值(在本例中为ind)。我们使用2列(高和低)将矢量转换为矩阵,并使用do.callcbind来获得最终的数据帧。

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

非常感谢您,您是否介意解释它 - 这似乎相当复杂 – 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 
相关问题