mira
mira

Reputation: 64

extract subset from data.frame

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

Answers (1)

A5C1D2H2I1M1N2O1R2T1
A5C1D2H2I1M1N2O1R2T1

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

Related Questions