使用 R:将矩阵转换为向量序列以实现阶函数的可变参数方法
Using R: casting a matrix as a sequence of vectors to implement a variadic approach for order function
排序函数描述了它在列表中的读取方式
?order
...
a sequence of numeric, complex, character or logical vectors, all of the same length, or a classed R object.
-----------------------------------------------------
> order
function (..., na.last = TRUE, decreasing = FALSE, method = c("auto",
"shell", "radix"))
{
z <- list(...)
decreasing <- as.logical(decreasing)
if (length(z) == 1L && is.numeric(x <- z[[1L]]) && !is.object(x) &&
length(x) > 0) {
if (.Internal(sorted_fpass(x, decreasing, na.last)))
return(seq_along(x))
}
大多数人使用 order
以一种被黑的、非可变的形式:
myData.sorted = myData[ order(-myData[,date.idx],-myData[,(1+date.idx)]), ];
我写了一个函数来使这个表单可变:
#########################################
## how I want it, doesn't work
#fdf = sdf[order(vecs), ];
#########################################
## non-variadic approach, does work
fdf = sdf[order( vecs[,1],vecs[,2],vecs[,3] ), ];
所以我有一个矩阵,我想根据它的可变列数来分解它,然后将该矩阵转换为 order
函数可以处理的向量序列。 unlist
?也许 as.list
?
如何根据列数将矩阵转换为向量序列?
更新
convertDateStringToFormat = function (strvec,format.out="%Y",format.in="%Y-%m-%d %H:%M:%S",numeric=TRUE)
{
p.obj = strptime(strvec, format=format.in);
o.obj = strftime(p.obj, format=format.out);
if(numeric) { as.numeric(o.obj); } else { o.obj; }
}
library(datasets);
data(iris);
df = iris[1:10,];
df$date.strings = c("3/24/2010 18:33", "9/3/2009 17:28", "10/14/2009 11:40", "7/3/2015 11:16","11/18/2010 1:29","4/23/2011 0:08","10/6/2010 11:13","7/26/2009 13:23","4/9/2008 13:40","8/20/2008 11:32");
df$year = convertDateStringToFormat(df$date.strings,"%Y","%m/%d/%Y %H:%M");
df$week = convertDateStringToFormat(df$date.strings,"%W","%m/%d/%Y %H:%M");
df$day = convertDateStringToFormat(df$date.strings,"%j","%m/%d/%Y %H:%M");
df$date.strings = NULL;
> df
Sepal.Length Sepal.Width Petal.Length Petal.Width Species year week day
1 5.1 3.5 1.4 0.2 setosa 2010 12 83
2 4.9 3.0 1.4 0.2 setosa 2009 35 246
3 4.7 3.2 1.3 0.2 setosa 2009 41 287
4 4.6 3.1 1.5 0.2 setosa 2015 26 184
5 5.0 3.6 1.4 0.2 setosa 2010 46 322
6 5.4 3.9 1.7 0.4 setosa 2011 16 113
7 4.6 3.4 1.4 0.3 setosa 2010 40 279
8 5.0 3.4 1.5 0.2 setosa 2009 29 207
9 4.4 2.9 1.4 0.2 setosa 2008 14 100
10 4.9 3.1 1.5 0.1 setosa 2008 33 233
>
这里有一个 ... 步骤,但我们得到一个矩阵 vecs
如下所示:
vecs = matrix(
c(2010,2009,2009,2015,2010,2011,2010,2009,2008,2008,
-12,-35,-41,-26,-46,-16,-40,-29,-14,-33,
83,246,287,184,322,113,279,207,100,233),
nrow=10,ncol=3,byrow=F);
> vecs
[,1] [,2] [,3]
[1,] 2010 -12 83
[2,] 2009 -35 246
[3,] 2009 -41 287
[4,] 2015 -26 184
[5,] 2010 -46 322
[6,] 2011 -16 113
[7,] 2010 -40 279
[8,] 2009 -29 207
[9,] 2008 -14 100
[10,] 2008 -33 233
>
所以我试试这个:vec2 = as.data.frame(vecs); class(vec2) = "list";
基于另一个 post (alfymbohm) How to convert a matrix to a list of column-vectors in R?
目前,这有效:
df[order( vecs[,1],vecs[,2],vecs[,3] ), ];
Sepal.Length Sepal.Width Petal.Length Petal.Width Species year week day
10 4.9 3.1 1.5 0.1 setosa 2008 33 233
9 4.4 2.9 1.4 0.2 setosa 2008 14 100
3 4.7 3.2 1.3 0.2 setosa 2009 41 287
2 4.9 3.0 1.4 0.2 setosa 2009 35 246
8 5.0 3.4 1.5 0.2 setosa 2009 29 207
5 5.0 3.6 1.4 0.2 setosa 2010 46 322
7 4.6 3.4 1.4 0.3 setosa 2010 40 279
1 5.1 3.5 1.4 0.2 setosa 2010 12 83
6 5.4 3.9 1.7 0.4 setosa 2011 16 113
4 4.6 3.1 1.5 0.2 setosa 2015 26 184
而我想要的工作失败了。我用vec2
来区分
vec2 = as.data.frame(vecs); class(vec2) = "list";
df[order(vec2), ];
它(order
函数)抛出以下错误:
Error in order(vec2) : unimplemented type 'list' in 'orderVector1'
我认为您的方法是我在其他地方找到的按名单演员的想法。
理想情况下,我想要一个函数,例如
vec2 = castMatrixToSequenceOfLists(vecs);
哪里
castMatrixToSequenceOfLists = function(mat)
{
list_length = ncol(mat);
out_list = vector("list", list_length);
for(i in 1:list_length)
{
out_list[[i]] = mat[,i]; # double brackets [[1]]
}
out_list;
}
没有成功!抛出相同的错误(order
函数):
vec2 = castMatrixToSequenceOfLists(vecs);
df[order(vec2), ];
Error in order(vec2) : unimplemented type 'list' in 'orderVector1'
同样,可变参数当前不起作用,因为根据 order
.
的手册,矩阵不是“向量序列”
如何根据列数将矩阵转换为向量序列,以便 order
函数接受它?
解决方案
mat_order <- function(x) do.call(order, split(x, (seq(x) - 1) %/% nrow(x)))
> df[mat_order(vecs),]
Sepal.Length Sepal.Width Petal.Length Petal.Width Species year week day
10 4.9 3.1 1.5 0.1 setosa 2008 33 233
9 4.4 2.9 1.4 0.2 setosa 2008 14 100
3 4.7 3.2 1.3 0.2 setosa 2009 41 287
2 4.9 3.0 1.4 0.2 setosa 2009 35 246
8 5.0 3.4 1.5 0.2 setosa 2009 29 207
5 5.0 3.6 1.4 0.2 setosa 2010 46 322
7 4.6 3.4 1.4 0.3 setosa 2010 40 279
1 5.1 3.5 1.4 0.2 setosa 2010 12 83
6 5.4 3.9 1.7 0.4 setosa 2011 16 113
4 4.6 3.1 1.5 0.2 setosa 2015 26 184
这在可变参数形式中按预期工作。
这行得通吗:
x <- matrix(rnorm(100), ncol=10)
lapply(1:ncol(x), function(i)x[,i])
# [[1]]
# [1] 0.48517941 -0.17305691 -0.77043863 0.60336573 -1.45311257 0.79958015 1.13640966 0.02676497 0.29389045
# [10] -0.01102340
#
# [[2]]
# [1] -0.54202918 -0.31705192 -0.54335095 0.95893715 1.50479417 0.30277200 0.89060424 1.04398275 -0.05292274
# [10] -1.08171141
#
# [[3]]
# [1] -0.4263822 -0.7633086 -0.0920494 -0.8624237 0.4733904 1.1280913 -1.3591717 -2.0045355 -0.9451451 0.5850331
#
# [[4]]
# [1] 0.43011274 -0.31818318 -0.82670988 -1.41186748 -0.11159258 0.97936154 -0.96050860 -0.05459925 -0.64583762
# [10] -1.05754833
#
# [[5]]
# [1] 0.03352171 -1.41914682 -0.65342097 -0.65543412 -0.64277411 0.20129441 0.79787560 0.74036594 0.85009985
# [10] 0.57234638
#
# [[6]]
# [1] 1.53409626 -0.09687169 0.03232748 -0.29846023 -1.68693869 -0.35000084 -0.01507354 0.67449541 0.32737139
# [10] -0.25879175
#
# [[7]]
# [1] -0.03431753 -0.73440722 1.60681714 0.05675589 -0.91227635 -0.82333341 1.24233167 -0.67889010 0.15424119
# [10] 0.11909912
#
# [[8]]
# [1] -0.31600385 1.05633518 1.39758192 0.46613354 -1.56959308 0.01917428 -0.45930649 -0.90180761 0.14538694
# [10] 0.19565070
#
# [[9]]
# [1] 0.24165283 1.14789319 -0.01238587 -0.20014950 0.73042111 0.47187272 2.63819369 -0.81273739 -1.83783324
# [10] 0.59991982
#
# [[10]]
# [1] -1.0260512 -2.1172737 1.3514048 0.7677437 -0.9399838 -1.0775248 1.2656769 -0.5748148 -1.8108845 0.1093450
如果您想将矩阵的列传递给 order
就像调用 order(mat[,1], mat[,2], mat[,3])
等一样,那么这一行函数可以实现:
mat_order <- function(x) do.call(order, split(x, (seq(x) - 1) %/% nrow(x)))
它首先使用一些模块化数学将矩阵列 split
转换为向量列表,然后对结果使用 do.call(order, ...)
,其效果是传递每个列表元素(即每个向量)作为变量。
排序函数描述了它在列表中的读取方式
?order
...
a sequence of numeric, complex, character or logical vectors, all of the same length, or a classed R object.
-----------------------------------------------------
> order
function (..., na.last = TRUE, decreasing = FALSE, method = c("auto",
"shell", "radix"))
{
z <- list(...)
decreasing <- as.logical(decreasing)
if (length(z) == 1L && is.numeric(x <- z[[1L]]) && !is.object(x) &&
length(x) > 0) {
if (.Internal(sorted_fpass(x, decreasing, na.last)))
return(seq_along(x))
}
大多数人使用 order
以一种被黑的、非可变的形式:
myData.sorted = myData[ order(-myData[,date.idx],-myData[,(1+date.idx)]), ];
我写了一个函数来使这个表单可变:
#########################################
## how I want it, doesn't work
#fdf = sdf[order(vecs), ];
#########################################
## non-variadic approach, does work
fdf = sdf[order( vecs[,1],vecs[,2],vecs[,3] ), ];
所以我有一个矩阵,我想根据它的可变列数来分解它,然后将该矩阵转换为 order
函数可以处理的向量序列。 unlist
?也许 as.list
?
如何根据列数将矩阵转换为向量序列?
更新
convertDateStringToFormat = function (strvec,format.out="%Y",format.in="%Y-%m-%d %H:%M:%S",numeric=TRUE)
{
p.obj = strptime(strvec, format=format.in);
o.obj = strftime(p.obj, format=format.out);
if(numeric) { as.numeric(o.obj); } else { o.obj; }
}
library(datasets);
data(iris);
df = iris[1:10,];
df$date.strings = c("3/24/2010 18:33", "9/3/2009 17:28", "10/14/2009 11:40", "7/3/2015 11:16","11/18/2010 1:29","4/23/2011 0:08","10/6/2010 11:13","7/26/2009 13:23","4/9/2008 13:40","8/20/2008 11:32");
df$year = convertDateStringToFormat(df$date.strings,"%Y","%m/%d/%Y %H:%M");
df$week = convertDateStringToFormat(df$date.strings,"%W","%m/%d/%Y %H:%M");
df$day = convertDateStringToFormat(df$date.strings,"%j","%m/%d/%Y %H:%M");
df$date.strings = NULL;
> df
Sepal.Length Sepal.Width Petal.Length Petal.Width Species year week day
1 5.1 3.5 1.4 0.2 setosa 2010 12 83
2 4.9 3.0 1.4 0.2 setosa 2009 35 246
3 4.7 3.2 1.3 0.2 setosa 2009 41 287
4 4.6 3.1 1.5 0.2 setosa 2015 26 184
5 5.0 3.6 1.4 0.2 setosa 2010 46 322
6 5.4 3.9 1.7 0.4 setosa 2011 16 113
7 4.6 3.4 1.4 0.3 setosa 2010 40 279
8 5.0 3.4 1.5 0.2 setosa 2009 29 207
9 4.4 2.9 1.4 0.2 setosa 2008 14 100
10 4.9 3.1 1.5 0.1 setosa 2008 33 233
>
这里有一个 ... 步骤,但我们得到一个矩阵 vecs
如下所示:
vecs = matrix(
c(2010,2009,2009,2015,2010,2011,2010,2009,2008,2008,
-12,-35,-41,-26,-46,-16,-40,-29,-14,-33,
83,246,287,184,322,113,279,207,100,233),
nrow=10,ncol=3,byrow=F);
> vecs
[,1] [,2] [,3]
[1,] 2010 -12 83
[2,] 2009 -35 246
[3,] 2009 -41 287
[4,] 2015 -26 184
[5,] 2010 -46 322
[6,] 2011 -16 113
[7,] 2010 -40 279
[8,] 2009 -29 207
[9,] 2008 -14 100
[10,] 2008 -33 233
>
所以我试试这个:vec2 = as.data.frame(vecs); class(vec2) = "list";
基于另一个 post (alfymbohm) How to convert a matrix to a list of column-vectors in R?
目前,这有效:
df[order( vecs[,1],vecs[,2],vecs[,3] ), ];
Sepal.Length Sepal.Width Petal.Length Petal.Width Species year week day
10 4.9 3.1 1.5 0.1 setosa 2008 33 233
9 4.4 2.9 1.4 0.2 setosa 2008 14 100
3 4.7 3.2 1.3 0.2 setosa 2009 41 287
2 4.9 3.0 1.4 0.2 setosa 2009 35 246
8 5.0 3.4 1.5 0.2 setosa 2009 29 207
5 5.0 3.6 1.4 0.2 setosa 2010 46 322
7 4.6 3.4 1.4 0.3 setosa 2010 40 279
1 5.1 3.5 1.4 0.2 setosa 2010 12 83
6 5.4 3.9 1.7 0.4 setosa 2011 16 113
4 4.6 3.1 1.5 0.2 setosa 2015 26 184
而我想要的工作失败了。我用vec2
来区分
vec2 = as.data.frame(vecs); class(vec2) = "list";
df[order(vec2), ];
它(order
函数)抛出以下错误:
Error in order(vec2) : unimplemented type 'list' in 'orderVector1'
我认为您的方法是我在其他地方找到的按名单演员的想法。
理想情况下,我想要一个函数,例如
vec2 = castMatrixToSequenceOfLists(vecs);
哪里
castMatrixToSequenceOfLists = function(mat)
{
list_length = ncol(mat);
out_list = vector("list", list_length);
for(i in 1:list_length)
{
out_list[[i]] = mat[,i]; # double brackets [[1]]
}
out_list;
}
没有成功!抛出相同的错误(order
函数):
vec2 = castMatrixToSequenceOfLists(vecs);
df[order(vec2), ];
Error in order(vec2) : unimplemented type 'list' in 'orderVector1'
同样,可变参数当前不起作用,因为根据 order
.
如何根据列数将矩阵转换为向量序列,以便 order
函数接受它?
解决方案
mat_order <- function(x) do.call(order, split(x, (seq(x) - 1) %/% nrow(x)))
> df[mat_order(vecs),]
Sepal.Length Sepal.Width Petal.Length Petal.Width Species year week day
10 4.9 3.1 1.5 0.1 setosa 2008 33 233
9 4.4 2.9 1.4 0.2 setosa 2008 14 100
3 4.7 3.2 1.3 0.2 setosa 2009 41 287
2 4.9 3.0 1.4 0.2 setosa 2009 35 246
8 5.0 3.4 1.5 0.2 setosa 2009 29 207
5 5.0 3.6 1.4 0.2 setosa 2010 46 322
7 4.6 3.4 1.4 0.3 setosa 2010 40 279
1 5.1 3.5 1.4 0.2 setosa 2010 12 83
6 5.4 3.9 1.7 0.4 setosa 2011 16 113
4 4.6 3.1 1.5 0.2 setosa 2015 26 184
这在可变参数形式中按预期工作。
这行得通吗:
x <- matrix(rnorm(100), ncol=10)
lapply(1:ncol(x), function(i)x[,i])
# [[1]]
# [1] 0.48517941 -0.17305691 -0.77043863 0.60336573 -1.45311257 0.79958015 1.13640966 0.02676497 0.29389045
# [10] -0.01102340
#
# [[2]]
# [1] -0.54202918 -0.31705192 -0.54335095 0.95893715 1.50479417 0.30277200 0.89060424 1.04398275 -0.05292274
# [10] -1.08171141
#
# [[3]]
# [1] -0.4263822 -0.7633086 -0.0920494 -0.8624237 0.4733904 1.1280913 -1.3591717 -2.0045355 -0.9451451 0.5850331
#
# [[4]]
# [1] 0.43011274 -0.31818318 -0.82670988 -1.41186748 -0.11159258 0.97936154 -0.96050860 -0.05459925 -0.64583762
# [10] -1.05754833
#
# [[5]]
# [1] 0.03352171 -1.41914682 -0.65342097 -0.65543412 -0.64277411 0.20129441 0.79787560 0.74036594 0.85009985
# [10] 0.57234638
#
# [[6]]
# [1] 1.53409626 -0.09687169 0.03232748 -0.29846023 -1.68693869 -0.35000084 -0.01507354 0.67449541 0.32737139
# [10] -0.25879175
#
# [[7]]
# [1] -0.03431753 -0.73440722 1.60681714 0.05675589 -0.91227635 -0.82333341 1.24233167 -0.67889010 0.15424119
# [10] 0.11909912
#
# [[8]]
# [1] -0.31600385 1.05633518 1.39758192 0.46613354 -1.56959308 0.01917428 -0.45930649 -0.90180761 0.14538694
# [10] 0.19565070
#
# [[9]]
# [1] 0.24165283 1.14789319 -0.01238587 -0.20014950 0.73042111 0.47187272 2.63819369 -0.81273739 -1.83783324
# [10] 0.59991982
#
# [[10]]
# [1] -1.0260512 -2.1172737 1.3514048 0.7677437 -0.9399838 -1.0775248 1.2656769 -0.5748148 -1.8108845 0.1093450
如果您想将矩阵的列传递给 order
就像调用 order(mat[,1], mat[,2], mat[,3])
等一样,那么这一行函数可以实现:
mat_order <- function(x) do.call(order, split(x, (seq(x) - 1) %/% nrow(x)))
它首先使用一些模块化数学将矩阵列 split
转换为向量列表,然后对结果使用 do.call(order, ...)
,其效果是传递每个列表元素(即每个向量)作为变量。