我在R中有两个数据框,看起来像这样。
> df
Var1 Freq
1 0.01 1
2 1 27
3 100 27
4 1000 488
5 2000 4
6 5000 7
7 50000 7
8 100000 1
> return_matrix
Var1 Freq
1 0.00001 0
2 0.01 0
3 1 0
4 8 0
5 100 0
6 200 0
7 500 0
8 1000 0
9 2000 0
10 5000 0
11 10000 0
12 50000 0
13 100000 0
14 200000 0
15 500000 0
16 1000000 0
17 10000000 0
18 100000000 0
19 1000000000 0
我想像上面数据框的Vlookup那样做,以便输出如下所示:
> combined
Var1 Freq
1 0.00001 0
2 0.01 1
3 1 27
4 8 0
5 100 27
6 200 0
7 500 0
8 1000 488
9 2000 4
10 5000 7
11 10000 0
12 50000 7
13 100000 1
14 200000 0
15 500000 0
16 1000000 0
17 10000000 0
18 100000000 0
我尝试使用下面提到的R代码在R中执行合并。但是我没有像上面那样得到预期的结果。你能帮帮我吗?
> combined_matrix <- merge(return_matrix, df, by = "Var1" )
> combined_matrix
Var1 Freq.x Freq.y
1 0.01 0 1
2 1 0 27
3 100 0 27
4 1000 0 488
5 100000 0 1
6 2000 0 4
7 5000 0 7
8 50000 0 7
答案 0 :(得分:2)
这里没有必要合并任何东西。
id <- match(return_matrix$Var1, df$Var1, nomatch = 0L)
return_matrix$Freq[id != 0] <- df$Freq[id]
诀窍。
此代码将通过多种方式优于任何merge
或plyr
解决方案。在我的机器上进行以下模拟时,它比ddply
快约100倍,比merge
快约10倍:
library(plyr)
library(rbenchmark)
df <- data.frame(
Var1 = c(0.01, 1, 100, 1000, 2000, 5000, 50000,100000),
Freq = c(1,27,27,488,4,7,7,1)
)
return_matrix <- data.frame(
Var1 = c(0.00001,0.01,1,8,100,200,500,1000,2000,5000,
10000,50000,100000,200000,500000,1e6,1e7,1e8),
Freq = 0
)
codeJM <- function(df, return_matrix){
id <- match(return_matrix$Var1, df$Var1, nomatch = 0L)
return_matrix$Freq[id != 0] <- df$Var1[id]
return_matrix
}
codemerge <- function(df, return_matrix){
combined_matrix <- merge(return_matrix, df, by = "Var1" , all = TRUE)
combined_matrix$Freq <- combined_matrix$Freq.x+combined_matrix$Freq.y
combined_matrix$Freq.x <- combined_matrix$Freq.y <- NULL
combined_matrix
}
codeddply <- function(df, return_matrix){
full <- rbind(df,return_matrix)
combined <- ddply(full ,.(Var1),function(x)
data.frame(Var1=x$Var1[1],Freq=sum(x$Freq)))
combined
}
benchmark(
codemerge(df, return_matrix),
codeJM(df, return_matrix),
codeddply(df, return_matrix),
replications = 1000
)
给出:
test replications elapsed relative user.self
3 codeddply(df, return_matrix) 1000 5.38 107.6 5.37
2 codeJM(df, return_matrix) 1000 0.05 1.0 0.05
1 codemerge(df, return_matrix) 1000 0.51 10.2 0.52
答案 1 :(得分:1)
您可以使用Joris建议的匹配函数,也可以使用plyr包中的ddply函数:
library(plyr)
full <- rbind(df,return_matrix)
combined <- ddply(full ,.(Var1),function(x) data.frame(Var1=x$Var1[1],Freq=sum(x$Freq)))
这将汇总Freq中的值,即使它们在return_matrix
中不为0答案 2 :(得分:1)
您仍然可以通过选择merge
来使用all.x = TRUE
,这会保留所有行:
c<-merge(return_matrix, df, by = "Var1", all.x = TRUE)
这将创建第二个freq列,但您可以相当轻松地清理它
c<-c[, -2]
c[,2][which(is.na(c[,2]))]<- 0