2012-09-06 110 views
2

DF使用plyr在兩個數據匹配的列值幀

av bv tv u l value   s 
30 120 360 330 210 6600 0.005238424 
35 125 360 325 200 6875 0.005028887 
40 130 360 320 190 7150 0.004835468 
45 135 360 315 180 7425 0.004656377 
50 140 360 310 170 7700 0.004490078 
55 145 360 305 160 7975 0.004335247 
60 150 360 300 150 8250 0.004190739 
65 155 360 295 140 8525 0.004055554 
70 160 360 290 130 8800 0.003928818 
75 165 360 285 120 9075 0.003809763 
80 170 360 280 110 9350 0.003697711 

dput(DF)

df<-structure(list(av = c(30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 
80), bv = c(120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 
170), tv = c(360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 
360), u = c(330, 325, 320, 315, 310, 305, 300, 295, 290, 285, 
280), l = c(210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 
110), value = c(6600, 6875, 7150, 7425, 7700, 7975, 8250, 8525, 
8800, 9075, 9350), s = c(0.005238424, 0.00502888704, 0.00483546830769231, 
0.00465637688888889, 0.00449007771428572, 0.00433524744827586, 
0.0041907392, 0.00405555406451613, 0.003928818, 0.00380976290909091, 
0.00369771105882353)), .Names = c("av", "bv", "tv", "u", "l", 
"value", "s"), row.names = c(1L, 13L, 25L, 37L, 49L, 61L, 73L, 
85L, 97L, 109L, 121L), class = "data.frame") 

DF2

av bv tv u l value 
    30 120 0 0 0  0 
    30 120 20 0 0  0 
    30 120 40 10 0 550 
    30 120 60 30 0 1650 
    30 120 120 90 0 4950 
    30 120 180 150 30 6600 

dput(DF2)

df2<-structure(list(av = c(30, 30, 30, 30, 30, 30), bv = c(120, 120, 
120, 120, 120, 120), tv = c(0, 20, 40, 60, 120, 180), u = c(0, 
0, 10, 30, 90, 150), l = c(0, 0, 0, 0, 0, 30), value = c(0, 0, 
550, 1650, 4950, 6600)), .Names = c("av", "bv", "tv", "u", "l", 
"value"), row.names = c(1L, 2602L, 5203L, 7804L, 10405L, 13006L 
), class = "data.frame") 

我想要做的就是將的值加入dfdf2,其中df$bv == df2$bvdf2將在df中有更多相同的bv值,因此會有一些重複的s值。

我嘗試以下

 newDF <- ddply(df2, .(bv,tv), summarise, s = df[df$bv %in% df2$bv,]$s) 

雖然這不是爲我工作,也許是因爲我真的不明白這個函數的可變參數。

真的所有其他列在這一點上是任意的,但我想保持整個數據幀不變。

回答

6

這將拉動相應的「S'項目的‘東風’到的匹配的行‘DF2’ :

df2$s <- df$s[ match(df2$bv, df$bv)] 
df2 
#----------------------- 
     av bv tv u l value   s 
1  30 120 0 0 0  0 0.005238424 
2602 30 120 20 0 0  0 0.005238424 
5203 30 120 40 10 0 550 0.005238424 
7804 30 120 60 30 0 1650 0.005238424 
10405 30 120 120 90 0 4950 0.005238424 
13006 30 120 180 150 30 6600 0.005238424 

這會比'subset()'和'merge()'效率高很多。 Oooops。我沒有看到plyr部分。這將比任何plyr方法快得多,但這就是因爲我是一個base-R傢伙。如果你想與plyr做那麼這提供了什麼,我想你問:

> newDF <- ddply(df2, .(bv), summarise, s = df$s[match(df2$bv , df$bv)]) 
> newDF 
    bv   s 
1 120 0.005238424 
2 120 0.005238424 
3 120 0.005238424 
4 120 0.005238424 
5 120 0.005238424 
6 120 0.005238424 
1
dfsub<-data.frame(bv=df$bv,s=df$s) 
newdf<-merge(df2,dfsub,by="bv",all=TRUE) 

如果你不從df是不出現在df2添加刪除all=TRUE想多餘的值如

newdf<-merge(df2,dfsub,by="bv") 

編輯

對我來說,那將是:

df2sub<-data.frame(bv=df2$bv) 
dfsub<-data.frame(bv=df$bv,s=df$s) 
newdf<-merge(df2sub,dfsub,by="bv") 

newdf 
    bv   s 
1 120 0.005238424 
2 120 0.005238424 
3 120 0.005238424 
4 120 0.005238424 
5 120 0.005238424 
6 120 0.005238424 
+0

我認爲第一行可以被編輯: – Doug

+0

dfsub < - DF [,C( 'BV', 'S')] – Doug

+0

如果那更快你燁。我認爲這會更容易看到我在做什麼。這有幫助嗎? –

4

雖然問題已經回答了,我想我會用data.table包給你一個不同的方法對這一問題。

library(data.table) 
df <- data.table(df) 
setkey(df, bv) 
df2 <- data.table(df2) 
setkey(df2, bv) 
df2[df, roll = T] 

我想象你的全部數據集比這個簡單的例子大得多,因此,你可能會得到更好的性能與用data.table

> system.time(df2[df, roll = T]) 
    user system elapsed 
    0.007 0.000 0.008 
> system.time(ddply(df2, .(bv), summarise, s = df$s[match(df2$bv , df$bv)])) 
    user system elapsed 
    0.013 0.001 0.065 
相關問題