2017-08-16 44 views
1

我有兩個數據幀:條件更換使用行/列名的比賽從其他數據幀

id <- c("a", "b", "c") 
a <- 0 
b <- 0 
c <- 0 
df1 <- data.frame(id, a, b, c) 

    id a b c 
1 a 0 0 0 
2 b 0 0 0 
3 c 0 0 0 

num <- c("a", "c", "c") 
partner <- c("b", "b", "a") 
value <- c("10", "20", "30") 
df2 <- data.frame(num, partner, value) 

    num partner value 
1 a  b 10 
2 c  b 20 
3 c  a 30 

我想在每一個實例df1$id==df2$num & colnames(df1)==df2$partnerdf2$value更換零的df1。所以輸出應該是這樣的:

a <- c(0, 0, 30) 
b <- c(10, 0, 20) 
c <- c(0, 0, 0) 
df.nice <- data.frame(id, a, b, c) 

    id a b c 
1 a 0 10 0 
2 b 0 0 0 
3 c 30 20 0 

我可以用下面的替換單個細胞:

df1$b[df1$id=="a"] <- ifelse(df2$num=="a" & df2$partner=="b", df2$value, 0) 

,但我通過一個大的數據幀都可能df1行/列的組合,需要週期。我懷疑這涉及plyr和匹配在一起,但不能完全弄清楚如何。

更新

感謝@MikeH,我轉向使用重塑。這似乎工作:

df.nice <- melt(df2, id=c("num", "partner")) 
df.nice <- dcast(test.nice, num ~ partner, value.var="value") 

產生這樣的:

num a b 
1 a <NA> 10 
2 c 30 20 

我需要的所有可能的行/列的組合,但是,所有的表示爲零。有沒有辦法讓重塑從另一個數據框(例如,df1)獲取行和列?還是應該在重塑後綁定那些?

+0

'rowname(DF1)'? – PoGibas

+0

你真的需要一個替換嗎?或者你實際上只是試圖將'df2'重塑爲'df.nice'的格式? –

+0

如果包含所有可能的行/列組合,@Mike H. reshape將起作用。現在就試試,謝謝 – hoho

回答

0

如果你想更換(而不是重塑)我認爲,一個簡單的基礎R的解決辦法是要做到:

idxs <- t(mapply(cbind, match(df2$num, df1$id), match(df2$partner, names(df1)))) 
df1[idxs] <- df2$value 

df1 
    id a b c 
1 a 0 10 0 
2 b 0 0 0 
3 c 30 20 0 

注意,我建行/列組合查找使用t(mapply(...))更換。當您選擇像df1[idxs]這樣選擇時,它會轉換爲矩陣(以選擇特定的行/列組合),然後轉換回data.frame


我不得不使用stringsAsFactors = FALSE所以值將正確地註冊(而不是數字)在數據讀取。

數據:

df2 <- data.frame(num, partner, value, stringsAsFactors = F) 
df1 <- data.frame(id, a, b, c, stringsAsFactors = F)