Reputation: 186
Suppose I have the following dataframe:
DF <- data.frame(Col1=c(2,2,1),Col2=c(2,7,5),Col3=c(9,6,4))
I would like to know 2 things:
how can I get another field stating the index of the column where that row changes values. Hence, for the first row we'd get 1 and 3, and for the second and third rows, 1, 2 and 3.
How to get a field of the "before and after"? for the first case, something like 2 -> 9, for the second and third, 2->7, 7-> 6 and 1 ->5, 5->4, respectively.
Upvotes: 1
Views: 338
Reputation: 4224
What about this:
x <- sapply(1:NCOL(df), function(x) rle(df[x,])$values)
Output of x:
[[1]]
Col2 Col3
1 2 9
[[2]]
Col1 Col2 Col3
2 2 7 6
[[3]]
Col1 Col2 Col3
3 1 5 4
Then if you'd like the full range of before/after values, you could use:
lapply(x,function(i) paste0(i,collapse="->"))
[[1]]
[1] "2->9"
[[2]]
[1] "2->7->6"
[[3]]
[1] "1->5->4"
Upvotes: 1
Reputation: 32548
apply(X = DF, MARGIN = 1, function(x) cumsum(rle(x)$lengths))
#[[1]]
#Col1 Col3
# 2 3
#[[2]]
#Col1 Col2 Col3
# 1 2 3
#[[3]]
#Col1 Col2 Col3
# 1 2 3
apply(X = DF, MARGIN = 1, function(x){
temp = unique(x)
if (length(temp) == 1){
temp
}else{
sapply(1:(length(temp)-1), function(i)
paste(temp[i:min(i+1, length(temp))], collapse = ">"))
}
})
#[[1]]
#[1] "2>9"
#[[2]]
#[1] "2>7" "7>6"
#[[3]]
#[1] "1>5" "5>4"
Upvotes: 1