Хорошо, это не так чисто, как решение mt1022, но оно не требует data.table
.Требуется dplyr
для функции case_when
и base
для всего остального.
Определение двух новых функций, find_conditions
и transform
.
find_conditions
немного громоздконо может быть полезно, так как вы можете легко добавить новые определения, если это необходимо.
find_conditions <- function(x){
x1 <- x
x1 <- case_when(
x1 == "PotHiUpOne" ~ c("pot", "hi", "up", "one"),
x1 == "PotHiUpTwo" ~ c("pot", "hi", "up", "two"),
x1 == "PotHiDownOne" ~ c("pot", "hi", "down", "one"),
x1 == "PotHiDownTwo" ~ c("pot", "hi", "down", "two"),
x1 == "PotLowUpOne" ~ c("pot", "low", "up", "one"),
x1 == "PotLowUpTwo" ~ c("pot", "low", "up", "two"),
x1 == "PotLowDownOne" ~ c("pot", "low", "down", "one"),
x1 == "PotLowDownTwo" ~ c("pot", "low", "down", "two"),
x1 == "PanHiUpOne" ~ c("pan", "hi", "up", "one"),
x1 == "PanHiUpTwo" ~ c("pan", "hi", "up", "two"),
x1 == "PanHiDownOne" ~ c("pan", "hi", "down", "one"),
x1 == "PanHiDownTwo" ~ c("pan", "hi", "down", "two"),
x1 == "PanLowUpOne" ~ c("pan", "low", "up", "one"),
x1 == "PanLowUpTwo" ~ c("pan", "low", "up", "two"),
x1 == "PanLowDownOne" ~ c("pan", "low", "down", "one"),
x1 == "PanLowDownTwo" ~ c("pan", "low", "down", "two")
)
if(NA %in% x1){
cat("Error: Input not recognized")
}
else{
return(x1)
}
}
transform
берет строку из df
и преобразует ее в нужную форму.Это зависит от функции find_conditions
, которую мы уже определили.
transform <- function(row){
row1 <- row[3:length(row)] # Forget about id and age columns, will put them back at the end
cols <- colnames(row1)[!is.na(row1)] # Get names of the columns which are not NA
cols <- substr(cols,1,nchar(cols)-1) # Slice off the last character (The number)
cols <- cols[!duplicated(cols)] # Columns should all have the same name now - find it by removing duplicates
vars <- find_conditions(cols) # Use our new find_conditions function to break it up into individual conditions
row1 <- row1[!is.na(row1)] # Keep only non-NA values
new_row <- c(row[1:2],row1,vars) # put id, age, row1, vars together
as.vector(unlist(new_row)) # Return as an unnamed vector
}
Теперь использовать эти две функции довольно просто:
l1 <- list() # Initialize empty list
for (i in 1:nrow(df)){
l1[[i]] <- transform(df[i,]) # Fill list with transformed rows
}
DF1 <- data.frame(do.call("rbind",l1)) # Bind the transformed rows together
Оставьте это в цикле, как вы сказали,не большой набор данных.Удачи!