在R中按列匹配ID附加列
Posted
技术标签:
【中文标题】在R中按列匹配ID附加列【英文标题】:appending columns by column matching ID in R 【发布时间】:2015-12-22 10:11:01 【问题描述】:所以我想要做的事情对我来说很难表达,但非常简单,我可以很容易地向你展示。标题是我对措辞的最佳猜测,需要编辑。
set.seed(1)
theta=matrix(rnorm(6,0,1),2,3)
M = c( 0 , 0 , 0 , 0, 1 ,
1, 0 , 0 , 0 , 1,
2 , 0 , 0 , 0, 2,
0 , 1 , 0 , 0 ,2,
1 , 1 , 0 , 0, 3,
0 , 2 , 0 , 0, 3)
M = matrix(M, nrow = 6,ncol= 5,byrow=T)
theta
[,1] [,2] [,3]
[1,] 0.4418121 1.962053 2.236691
[2,] 1.0931398 1.273616 1.050373
M
prod11 prod12 prod21 prod22 d
1 0 0 0 0 1
2 1 0 0 0 1
3 2 0 0 0 2
4 0 1 0 0 2
5 1 1 0 0 3
7 0 2 0 0 3
OUTPUT DESIRED
prod11 prod12 prod21 prod22 d theta1 theta2
1 0 0 0 0 1 0.4418121 1.0931398
2 1 0 0 0 1 0.4418121 1.0931398
3 2 0 0 0 2 1.962053 1.273616
4 0 1 0 0 2 1.962053 1.273616
5 1 1 0 0 3 2.236691 1.050373
7 0 2 0 0 3 2.236691 1.050373
【问题讨论】:
所以M
被存储为矩阵?
你能播种吗?那么,theta 现在的值是什么,
您的 d
列实际上不在示例数据中。同样,列没有命名。
【参考方案1】:
我会使用data.table
:
setDT(M)
M[, paste0("theta",1:2) := as.data.table(t(theta[, d]))]
> M
V1 V2 V3 V4 V5 theta1 theta2
1: 0 0 0 0 1 -1.2341141 0.4675928
2: 1 0 0 0 1 -1.2341141 0.4675928
3: 2 0 0 0 2 -0.6186437 1.5602801
4: 0 1 0 0 2 -0.6186437 1.5602801
5: 1 1 0 0 3 0.1233480 -0.3746259
6: 0 2 0 0 3 0.1233480 -0.3746259
我们需要as.data.table
或as.data.frame
,因为as.list
破坏了矩阵结果的维度,而:=
将只是unlist
来自t(theta[, d])
的结果
如果M
确实存储为矩阵(不清楚,因为您尚未命名它的维度),我建议您使用M <- data.table(M)
将其存储为data.table
(或data.frame
)。
为了完整起见,这里有一个纯矩阵表示法的解决方案:
M <- cbind(M, t(theta[, M[, "d"]]))
【讨论】:
【参考方案2】:与base R
:
mat1 <- cbind(M, apply(theta, 1, function(x) x[M[, "d"]]))
colnames(mat1) <- c(colnames(M), paste0("theta", 1:nrow(theta)))
# prod11 prod12 prod21 prod22 d theta1 theta2
# [1,] 0 0 0 0 1 -0.893800723 -0.3073283
# [2,] 1 0 0 0 1 -0.893800723 -0.3073283
# [3,] 2 0 0 0 2 -0.004822422 0.9881641
# [4,] 0 1 0 0 2 -0.004822422 0.9881641
# [5,] 1 1 0 0 3 0.839750360 0.7053418
# [6,] 0 2 0 0 3 0.839750360 0.7053418
函数的核心是x[M[, "d"]]
。正如 Micheal 的回答一样,我们可以用另一个矩阵中的向量对一个矩阵进行子集化。向量是 M 的“d”列,M[, "d"]
。如果该列有更随机的代码,我们将设置更健壮的查找。但是由于它匹配theta的列号,我们可以直接使用它。
我用apply
包裹它,因为它适用于矩阵。第二个参数1
表示函数应该按行执行(相当于theta[1, ]
和theta[2, ]
等等。如果我选择2
,x 将相当于theta[ ,1]
等等。
为了将列名与所需的输出相匹配,我们使用colnames
(一个可能的陷阱是尝试与数据帧一起使用的names()
)。
【讨论】:
【参考方案3】:我们可以使用merge()
:
theta <- t(theta) #transpose matrix
theta <- cbind(theta,seq(1:nrow(theta))) # add column "d" with row numbers
colnames(theta) <- c("theta1","theta2","d")
merge(M,theta)
# d prod11 prod12 prod21 prod22 theta1 theta2
#1 1 0 0 0 0 0.4418121 1.093140
#2 1 1 0 0 0 0.4418121 1.093140
#3 2 2 0 0 0 1.9620530 1.273616
#4 2 0 1 0 0 1.9620530 1.273616
#5 3 1 1 0 0 2.2366910 1.050370
#6 3 0 2 0 0 2.2366910 1.050370
数据
M <- c(0 , 0 , 0 , 0 , 1,
1 , 0 , 0 , 0 , 1,
2 , 0 , 0 , 0 , 2,
0 , 1 , 0 , 0 , 2,
1 , 1 , 0 , 0 , 3,
0 , 2 , 0 , 0 , 3)
M <- as.data.frame(matrix(M, nrow = 6,ncol= 5,byrow=TRUE))
colnames(M) <- c( "prod11","prod12","prod21","prod22", "d")
theta <-matrix(c(0.4418121, 1.962053, 2.236691,1.0931398, 1.273616, 1.05037), byrow=TRUE, nrow=2)
【讨论】:
以上是关于在R中按列匹配ID附加列的主要内容,如果未能解决你的问题,请参考以下文章
从 MySQL 中的时间戳排序表中按列选择第一个和最后一个匹配项