Let's say I got a table like this:
data <- c(1,2,3,6,5,6,9,"LC","LC","HC","HC","LC","HC","ALL")
attr(data,"dim") <- c(7,2)
data
[,1] [,2]
[1,] "1" "LC"
[2,] "2" "LC"
[3,] "3" "HC"
[4,] "6" "HC"
[5,] "5" "LC"
[6,] "6" "HC"
[7,] "9" "ALL"
Now I want to manipulate the data so it looks like this:
[,"LC"] [,"HC"] [,"ALL"]
[1,] "1" "3" "9"
[2,] "2" "6"
[3,] "5" "6"
Is there a way to do this in R or is it just impossible and should I try another开发者_开发知识库 way of getting access to my data?
You can get very close by using split
. This returns a list with the values you wanted and you can then use lapply
or any other list manipulation function:
split(data[, 1], data[, 2])
$ALL
[1] "9"
$HC
[1] "3" "6" "6"
$LC
[1] "1" "2" "5"
If you must have the output in matrix format, then I suggest you pad the short vectors with NA:
x <- split(data[, 1], data[, 2])
n <- max(sapply(x, length))
pad_with_na <- function(x, n, padding=NA){
c(x, rep(padding, n-length(x)))
}
sapply(x, pad_with_na, n)
This results in:
ALL HC LC
[1,] "9" "3" "1"
[2,] NA "6" "2"
[3,] NA "6" "5"
EXAMPLE DATA
I prefere to read data into data.frame as it check if vectors are of equal length.
data <- data.frame(X=c(1,2,3,6,5,6,9),
Y=c("LC","LC","HC","HC","LC","HC","ALL"))
CODE
data <- unstack(data, form=X~Y)# easier to read than split
Nmax <- do.call(max, lapply(data,length))
sapply(data, "[", seq(Nmax))# "borrowed" from other answer in SO
精彩评论