可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Say you want to convert a matrix to a list, where each element of the list contains one column. list() or as.list() obviously won't work, and until now I use a hack using the behaviour of tapply :
x
I'm not completely happy with this. Anybody knows a cleaner method I'm overlooking?
(for making a list filled with the rows, the code can obviously be changed to :
tapply(x,rep(1:nrow(x),ncol(x)),function(i)i)
)
回答1:
In the interests of skinning the cat, treat the array as a vector as if it had no dim attribute:
split(x, rep(1:ncol(x), each = nrow(x)))
回答2:
Gavin's answer is simple and elegant. But if there are many columns, a much faster solution would be:
lapply(seq_len(ncol(x)), function(i) x[,i])
The speed difference is 6x in the example below:
> x system.time( as.list(data.frame(x)) ) user system elapsed 1.24 0.00 1.22 > system.time( lapply(seq_len(ncol(x)), function(i) x[,i]) ) user system elapsed 0.2 0.0 0.2
回答3:
data.frames are stored as lists, I believe. Therefore coercion seems best:
as.list(as.data.frame(x)) > as.list(as.data.frame(x)) $V1 [1] 1 2 3 4 5 $V2 [1] 6 7 8 9 10
Benchmarking results are interesting. as.data.frame is faster than data.frame, either because data.frame has to create a whole new object, or because keeping track of the column names is somehow costly (witness the c(unname()) vs c() comparison)? The lapply solution provided by @Tommy is faster by an order of magnitude. The as.data.frame() results can be somewhat improved by coercing manually.
manual.coerce
回答4:
Converting to a data frame thence to a list seems to work:
> as.list(data.frame(x)) $X1 [1] 1 2 3 4 5 $X2 [1] 6 7 8 9 10 > str(as.list(data.frame(x))) List of 2 $ X1: int [1:5] 1 2 3 4 5 $ X2: int [1:5] 6 7 8 9 10
回答5:
Using plyrcan be really useful for things like this:
library("plyr") alply(x,2) $`1` [1] 1 2 3 4 5 $`2` [1] 6 7 8 9 10 attr(,"class") [1] "split" "list"
回答6:
I know this is anathema in R, and I don't really have a lot of reputation to back this up, but I'm finding a for loop to be rather more efficient. I'm using the following function to convert matrix mat to a list of its columns:
mat2list
Quick benchmark comparing with mdsummer's and the original solution:
x
回答7:
Under Some R Help site accessible via nabble.com I find:
c(unname(as.data.frame(x)))
as a valid solution and in my R v2.13.0 install this looks ok:
> y y [[1]] [1] 1 2 3 4 5 [[2]] [1] 6 7 8 9 10
Can't say anythng about performance comparisons or how clean it is ;-)
回答8:
You could use apply and then c with do.call
x
And it looks like it will preserve the column names, when added to the matrix.
colnames(x)
回答9:
In the trivial case where the number of columns is small and constant, then I've found that the fastest option is to simply hard-code the conversion:
mat2list
回答10:
convertRowsToList {BBmisc}
Convert rows (columns) of data.frame or matrix to lists.
BBmisc::convertColsToList(x)
ref: http://berndbischl.github.io/BBmisc/man/convertRowsToList.html