Reputation: 39
My R dataframe's headers include Forward, Backward, SideLeft, SideRight, and the new column I am trying to create is the Direction column.
The columns started with just TRUE/FALSE values, and I converted the TRUE values into the header names and made them all characters.
df[df==TRUE] <- colnames(df)[which(df==TRUE, arr.ind=TRUE)[,'col']]
Below is what the dataframe looks like:
> df
For Back SLeft SRight Direction
1 For FALSE FALSE FALSE FALSE
2 FALSE FALSE SLeft FALSE FALSE
3 FALSE Back FALSE FALSE FALSE
4 FALSE FALSE FALSE SRight FALSE
What I am trying to produce:
> df
For Back SLeft SRight Direction
1 For FALSE FALSE FALSE For
2 FALSE FALSE SLeft FALSE SLeft
3 FALSE Back FALSE FALSE Back
4 FALSE FALSE FALSE SRight SRight
With this code:
for (i in df){
for (index in 1:length(i)){
if (i[index]!="FALSE"){
df$Direction[i] = i[index]
}
}
}
What I am getting:
> df
For Back SLeft SRight Direction
1 For FALSE FALSE FALSE FALSE
2 FALSE FALSE SLeft FALSE FALSE
3 FALSE Back FALSE FALSE FALSE
4 FALSE FALSE FALSE SRight FALSE
First post, have mercy on my description/edits
Upvotes: 1
Views: 807
Reputation: 887118
We can use row/column indexing to extract the values. The column index is derived from max.col
, cbind
it with row index, extract the values and assign it to create 'Direction'
df$Direction <- df[1:4][cbind(seq_len(nrow(df)), max.col(df[1:4] != FALSE, 'first'))]
df
# For Back SLeft SRight Direction
#1 For FALSE FALSE FALSE For
#2 FALSE FALSE SLeft FALSE SLeft
#3 FALSE Back FALSE FALSE Back
#4 FALSE FALSE FALSE SRight SRight
If it was only a logical matrix, then also the max.col
to create the column index would work and is faster
df$Direction <- names(df)[1:4][cbind(seq_len(nrow(df)), max.col(df[1:4], 'first'))]
Upvotes: 1
Reputation: 79228
transform(df,Direction=df[(s<-which((df!=F),T))[order(s[,1]),]])
For Back SLeft SRight Direction
1 For FALSE FALSE FALSE For
2 FALSE FALSE SLeft FALSE SLeft
3 FALSE Back FALSE FALSE Back
4 FALSE FALSE FALSE SRight SRight
Upvotes: 1
Reputation: 145775
Data frame columns have to have a class, like numeric, character, factor, or logical. You had nice columns of logical class, and you should keep them that way!
"I converted the TRUE values into the header names and made them all characters" - this was a really bad idea. Don't do this step, and the rest will be easy. FALSE
and TRUE
are useful and have good meaning as logical values. As characters, "FALSE"
and "TRUE"
are more difficult to work with and will cause confusion when they don't behave like logicals.
If you still had TRUE
and FALSE
, then your solution would be
df$Direction = names(df)[apply(df, 1, which)]
Upvotes: 1