2014-12-06 56 views
1

我想知道如果我缺少執行以下操作的更快方式,而不是做一個費力的循環。使用數據框中的數據添加到數字矩陣中

說我有這樣的一個矩陣:

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 

現在,我想從以下數據框中添加值。在這裏,您可以看到'id1'和'id2'中列出的個人以及'val'中添加的值。

dfx <- structure(list(id1 = c("JW", "SZ", "SZ"), id2 = c("AK", "AK", 
"JW"), val = c(1.5, 2.5, 1)), .Names = c("id1", "id2", "val"), row.names = c(NA, 
-3L), class = "data.frame") 

#dfx 
# id1 id2 val 
#1 JW AK 1.5 
#2 SZ AK 2.5 
#3 SZ JW 1.0 

每個值應該被添加到應加入m1[SZ, AK]的矩陣e.g 2.5相應小區。但是,應該將相同的值加到轉置單元上,即2.5也應該加到m1[AK, SZ]

得到的矩陣應該是這樣的:

# 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」的每一行來實現:

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 

任何想法/更好的方式讚賞指針:

回答

1

一種可能的替代base在數據幀被再成形爲相同的尺寸的矩陣。這是通過首先將'id1'和'id2'轉換爲factor s來實現的,levels從'm1'中選取。然後xtabs用於整形。結果及其t轉換添加到'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 
0

你可以試試

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 

或者你可能嘗試data.table

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 
2

使用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 
+0

這是整潔,但不直接回答這個問題。它只會爲矩陣的一半增加價值。 – jalapic 2014-12-06 17:20:33

+0

沒有看到轉置組件。只要將索引轉換爲dfx,就可以執行相同的過程。 – 2014-12-06 17:38:08

+0

@BondedDust沒有什麼可以擊敗這個解決方案:-) – akrun 2014-12-08 10:58:36

相關問題