R 使用数据帧中的数据添加到数值矩阵
我想知道除了做一个费力的循环之外,我是否缺少了一个更快的方法来完成下面的工作 假设我有这样一个矩阵:R 使用数据帧中的数据添加到数值矩阵,r,matrix,R,Matrix,我想知道除了做一个费力的循环之外,我是否缺少了一个更快的方法来完成下面的工作 假设我有这样一个矩阵: m1 <- structure(c(0, 2, 2, 1, 0, 1, 1, 1, 0), .Dim = c(3L, 3L), .Dimnames = list( c("AK", "JW", "SZ"), c("AK", "JW", "SZ"))) #m1 # AK JW SZ # AK 0 1 1 # JW 2 0 1 # SZ 2 1 0 例如,可以
m1 <- structure(c(0, 2, 2, 1, 0, 1, 1, 1, 0), .Dim = c(3L, 3L), .Dimnames = list(
c("AK", "JW", "SZ"), c("AK", "JW", "SZ")))
#m1
# AK JW SZ
# AK 0 1 1
# JW 2 0 1
# SZ 2 1 0
例如,可以通过创建一个循环来实现这一点,该循环基本上对“dfx”的每一行执行此操作:
m1[rownames(m1)=="JW",rownames(m1)=="AK"] <- m1[rownames(m1)=="JW",rownames(m1)=="AK"] + 1.5
m1[rownames(m1)=="AK",rownames(m1)=="JW"] <- m1[rownames(m1)=="AK",rownames(m1)=="JW"] + 1.5
m1[行名(m1)=“JW”,行名(m1)=“AK”]您可以尝试
library(reshape2)
Un1 <- sort(unique(unlist(dfx[,1:2])))
dfy <- expand.grid(id1=Un1, id2=Un1)
m2 <- acast(merge(dfx,dfy, all=TRUE), id1~id2, value.var='val', fill=0)
m2[upper.tri(m2)] <- m2[lower.tri(m2)]
m1+m2
# AK JW SZ
#AK 0.0 2.5 3.5
#JW 3.5 0.0 2.0
#SZ 4.5 2.0 0.0
一种可能的base
替代方案,其中数据帧被重塑为与矩阵相同的尺寸。这是通过首先将“id1”和“id2”转换为因子
s,并从“m1”中选择级别
来实现的。然后使用xtabs
进行整形。结果及其t
transpose被添加到“m1”中
dfx[ , c("id1", "id2")] <- lapply(dfx[ , c("id1", "id2")], function(x) factor(x, levels = rownames(m1)))
m2 <- xtabs(val ~ ., data = dfx)
m1 + m2 + t(m2)
# AK JW SZ
# AK 0.0 2.5 3.5
# JW 3.5 0.0 2.0
# SZ 4.5 2.0 0.0
dfx[,c(“id1”,“id2”)]使用cbind(x,y)作为赋值索引是一种标准的R策略:
m1[with(dfx, cbind(id1,id2)) ] <- m1[with(dfx, cbind(id1,id2)) ]+ # the prior values
dfx$val # the new values
m1
#-------------------
AK JW SZ
AK 0.0 1 1
JW 3.5 0 1
SZ 4.5 2 0
# Step 2 for the transposed addition
m1[with(dfx, cbind(id2,id1)) ] <- m1[with(dfx, cbind(id2,id1)) ]+
dfx$val
m1
#---------
AK JW SZ
AK 0.0 2.5 3.5
JW 3.5 0.0 2.0
SZ 4.5 2.0 0.0
m1[with(dfx,cbind(id1,id2))]这很简洁,但不能直接回答问题。它只为矩阵的一半增加了值,实际上没有看到转置成分。只需对交换到dfx中的索引执行相同的过程。@BondedDust没有任何东西能打败此解决方案:-)如果一步使用:(dfx,rbind(cbind(id2,id1),unname(cbind(id1,id2)))
?
library(data.table)
m2 <- acast(setkey(setDT(dfx), id1, id2)[
CJ(id1=Un1, id2=Un1)], id1~id2, value.var='val', fill=0)
m2+t(m2)+m1
# AK JW SZ
#AK 0.0 2.5 3.5
#JW 3.5 0.0 2.0
#SZ 4.5 2.0 0.0
dfx[ , c("id1", "id2")] <- lapply(dfx[ , c("id1", "id2")], function(x) factor(x, levels = rownames(m1)))
m2 <- xtabs(val ~ ., data = dfx)
m1 + m2 + t(m2)
# AK JW SZ
# AK 0.0 2.5 3.5
# JW 3.5 0.0 2.0
# SZ 4.5 2.0 0.0
m1[with(dfx, cbind(id1,id2)) ] <- m1[with(dfx, cbind(id1,id2)) ]+ # the prior values
dfx$val # the new values
m1
#-------------------
AK JW SZ
AK 0.0 1 1
JW 3.5 0 1
SZ 4.5 2 0
# Step 2 for the transposed addition
m1[with(dfx, cbind(id2,id1)) ] <- m1[with(dfx, cbind(id2,id1)) ]+
dfx$val
m1
#---------
AK JW SZ
AK 0.0 2.5 3.5
JW 3.5 0.0 2.0
SZ 4.5 2.0 0.0