Reputation: 53
I have a set of data as follows:
ID Distance
0 270.4170919
0 240.0230499
0 270.5878873
0 260.3663412
0 88.81341556
1 5564.323783
1 5625.862105
1 5709.559224
1 5809.231131
1 6286.892713
2 326.8418382
2 439.2376606
2 427.4494778
2 327.625258
2 326.3938459
3 601.9958829
3 323.1702281
3 755.3196593
There are five rows with ID
0, 1..325 with their corresponding values (Distance). I want to split the column (ID) based on rows (Distance) value and paste into multiple rows as follows:
A B C D E
0 88.81341556 240.0230499 260.3663412 270.4170919 270.5878873
1 5564.323783 5625.862105 5709.559224 5809.231131 6286.892713
2 326.3938459 326.8418382 327.625258 427.4494778 439.2376606
3 323.1702281 334.7788259 601.9958829 710.3485862 755.3196593
I have no clue where and how to start to code.
Upvotes: 1
Views: 51
Reputation: 17611
You can split based on ID, then sort each split. Then transpose it to match the matrix you want as output.
t(sapply(split(d$Distance, d$ID), sort))
# [,1] [,2] [,3] [,4] [,5]
#0 88.81342 240.0230 260.3663 270.4171 270.5879
#1 5564.32378 5625.8621 5709.5592 5809.2311 6286.8927
#2 326.39385 326.8418 327.6253 427.4495 439.2377
#3 323.17023 334.7788 601.9959 710.3486 755.3197
A few alternatives:
t(apply(matrix(d$Distance, nrow=5), 2, sort)) # rows aren't named here
do.call(rbind, lapply(split(d$Distance, d$ID), sort))
matrix(d[with(d, order(ID, Distance)), "Distance"],
ncol = 5,
byrow = TRUE,
dimnames = list(unique(d$ID))) # make sure IDs are in the right order
Sample data (note, the provided sample data is missing two values in ID 3, and I added them in my sample data here):
d <- read.table(text="
ID Distance
0 270.4170919
0 240.0230499
0 270.5878873
0 260.3663412
0 88.81341556
1 5564.323783
1 5625.862105
1 5709.559224
1 5809.231131
1 6286.892713
2 326.8418382
2 439.2376606
2 427.4494778
2 327.625258
2 326.3938459
3 601.9958829
3 323.1702281
3 755.3196593
3 334.7788259
3 710.3485862", header=TRUE)
Upvotes: 4
Reputation: 887661
Here is another option using unstack
t(unstack(d[do.call(order, d),], Distance~ID))
# [,1] [,2] [,3] [,4] [,5]
#X0 88.81342 240.0230 260.3663 270.4171 270.5879
#X1 5564.32378 5625.8621 5709.5592 5809.2311 6286.8927
#X2 326.39385 326.8418 327.6253 427.4495 439.2377
#X3 323.17023 334.7788 601.9959 710.3486 755.3197
Or with dcast
from data.table
library(data.table)
dcast(setDT(d)[order(ID, Distance)][, N:= 1:.N ,ID],
N~ID, value.var='Distance')[, N:= NULL]
NOTE: The output we got needs to be transposed as earlier.
Upvotes: 4