按组扫描第二个矩阵
Sweeping matrix by second matrix by group
我有一个问题,我无法找到类似的结果(也是因为我不确定如何对搜索本身进行措辞)。
我有一个包含多列的巨大矩阵。该矩阵还有一列指定每一行的“标识”。
我还有第二个矩阵,其中每个身份的每一列都有阈值。
我可以使用以下代码简化问题(尽管请记住我有很多列)。
temp_df=data.frame(a_name=rep(c("A","B", "C"), 20), matrix(rnorm(40),nrow=60, ncol=2))
其中包含:
> head(temp_df)
a_name X1 X2
1 A 0.31469191 -0.2763107
2 B -1.17477425 -0.2066650
3 C 0.10651550 0.1581325
4 A -1.88258477 -0.9280463
5 B -2.58260181 1.0322196
6 C 0.03027953 0.3110290
和阈值矩阵:
temp_limits=data.frame(a_name=c("A", "B", "C"), X1=c(1, 0.5, 0), x2=c(-1, -0.5, -0.25))
其中包含:
> temp_limits
a_name X1 x2
1 A 1.0 -1.00
2 B 0.5 -0.50
3 C 0.0 -0.25
我可以按如下方式处理矩阵以获得我想要的:
res_df=NULL
for(i in unique(temp_df$a_name)){
tdf=temp_df[temp_df$a_name==i,]
a_lim=temp_limits[temp_limits$a_name==i,]
tdf[, 2:3]=sweep(as.matrix(tdf[, 2:3]), MARGIN=2, a_lim[, 2:3], FUN=">" )
res_df=rbind(res_df, tdf)
}
这就是我想要的:
> head(res_df)
a_name X1 X2
1 A FALSE TRUE
4 A FALSE TRUE
7 A FALSE TRUE
10 A FALSE TRUE
13 A FALSE FALSE
16 A FALSE TRUE
但我认为这个实现太长、太麻烦,而且不是最优的。
我想我应该使用 group_by,因为我不确定如何进行。
有帮助吗?
你可以试试这个
cbind(temp_df[1], temp_df[-1] > temp_limits[match(temp_df$a_name, temp_limits$a_name), -1])
我们可以在这里使用连接
library(data.table)
setDT(temp_df)[temp_limits, .(a_name, X1 = X1 > i.X1, X2 = X2 > i.x2),
on = .(a_name)]
我有一个问题,我无法找到类似的结果(也是因为我不确定如何对搜索本身进行措辞)。 我有一个包含多列的巨大矩阵。该矩阵还有一列指定每一行的“标识”。 我还有第二个矩阵,其中每个身份的每一列都有阈值。 我可以使用以下代码简化问题(尽管请记住我有很多列)。
temp_df=data.frame(a_name=rep(c("A","B", "C"), 20), matrix(rnorm(40),nrow=60, ncol=2))
其中包含:
> head(temp_df)
a_name X1 X2
1 A 0.31469191 -0.2763107
2 B -1.17477425 -0.2066650
3 C 0.10651550 0.1581325
4 A -1.88258477 -0.9280463
5 B -2.58260181 1.0322196
6 C 0.03027953 0.3110290
和阈值矩阵:
temp_limits=data.frame(a_name=c("A", "B", "C"), X1=c(1, 0.5, 0), x2=c(-1, -0.5, -0.25))
其中包含:
> temp_limits
a_name X1 x2
1 A 1.0 -1.00
2 B 0.5 -0.50
3 C 0.0 -0.25
我可以按如下方式处理矩阵以获得我想要的:
res_df=NULL
for(i in unique(temp_df$a_name)){
tdf=temp_df[temp_df$a_name==i,]
a_lim=temp_limits[temp_limits$a_name==i,]
tdf[, 2:3]=sweep(as.matrix(tdf[, 2:3]), MARGIN=2, a_lim[, 2:3], FUN=">" )
res_df=rbind(res_df, tdf)
}
这就是我想要的:
> head(res_df)
a_name X1 X2
1 A FALSE TRUE
4 A FALSE TRUE
7 A FALSE TRUE
10 A FALSE TRUE
13 A FALSE FALSE
16 A FALSE TRUE
但我认为这个实现太长、太麻烦,而且不是最优的。 我想我应该使用 group_by,因为我不确定如何进行。 有帮助吗?
你可以试试这个
cbind(temp_df[1], temp_df[-1] > temp_limits[match(temp_df$a_name, temp_limits$a_name), -1])
我们可以在这里使用连接
library(data.table)
setDT(temp_df)[temp_limits, .(a_name, X1 = X1 > i.X1, X2 = X2 > i.x2),
on = .(a_name)]