Reputation: 64
I have a data.frame consisting of coordinates of points in 3D. There is 4 x 3 columns for 4 possible points A1,A2,A3,A4. In each row, there are exactly two non-zero points (any two of A1...A4).I was wondering if it would be possible to extract non-zero triplets to the new data.frame without using loops.
Original data.frame:
df<-data.frame(
rbind(
c(0,0,0,1,2,3,0,0,0,5,4,1),
c(1,2,2,1,2,3,0,0,0,0,0,0),
c(0,0,0,0,0,0,2,1,1,5,4,1),
c(0,0,0,1,3,1,2,1,1,0,0,0)
))
colnames(df) <- c("x1","y1","z1","x2","y2","z2","x3","y3","z3","x4","y4","z4")
What I want:
df2<-data.frame(
rbind(
c(1,2,3,5,4,1),
c(1,2,2,1,2,3),
c(2,1,1,5,4,1),
c(1,3,1,1,2,3)
))
colnames(df2) <- c("x5","y5","z5","x6","y6","z6")
Thanks
Upvotes: 2
Views: 222
Reputation: 193507
One easy way is to just use apply
, but technically, that is still using a loop.
t(apply(df, 1, function(x) x[x > 0]))
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 2 3 5 4 1
[2,] 1 2 2 1 2 3
[3,] 2 1 1 5 4 1
[4,] 1 3 1 2 1 1
You'll need to do a little (tiny) bit more work to convert it to a data.frame
and add the column names.
Without a loop, you can use something like this:
data.frame(matrix(df[df != 0], nrow = nrow(df)))
# X1 X2 X3 X4 X5 X6
# 1 1 1 3 2 1 4
# 2 2 1 3 2 1 4
# 3 2 2 3 1 5 1
# 4 1 2 1 1 5 1
Upvotes: 3