从数据帧获取另一个值

| 我是R编程的新手,并且刚刚开始学习它,因此,请您帮助我。 我有2个数据框:
the first(df1):

    V1 V2
    A  A 
    A  B 
    A  C 
    B  A 
    B  B 
    B  C 

etc
第二个(df2):
V1  Va   Vb
A   12   23
B   15   53
C   321  543
D   54   325
etc..
使用此代码生成示例数据。
df1 <- data.frame(
  V1 = rep(LETTERS[1:2], each = 3L),
  V2 = rep.int(LETTERS[1:3], 2L)
)
dfr2 <- data.frame(
  Va = c(12, 15, 312, 54),
  Vb = c(23, 53, 543, 325)
)
我需要从df2中提取Va和Vb并将它们放置在基于df1的V1和V2的df1中。 所以我想要这个输出: df3:
V1   V2  Va1  Vb1 Va2 Vb2
A    A   12    23  12  23
A    B   12    23  15  23
A    C   12    23  321 543
B    A   15    23  12   23
B    B   15    23  15   23
B    C   15    23  321  543
希望可以在R中完成十二个for循环:S。     
已邀请:
您可以使用match()的功能,前提是df1 $ V1中的名称是唯一的:
#some data
df1 <- data.frame(
  V1 = rep(c(\"A\",\"B\"),each=3),
  V2 = rep(LETTERS[1:3],2)  
)
df2 <- data.frame(V1=LETTERS[1:3],Va=1:3,Vb=3:1)

out <- cbind(df1,
  df2[match(df1$V1,df2$V1),-1],
  df2[match(df1$V2,df2$V1),-1]
)
names(out)[3:6] <- c(\"Va1\",\"Vb1\",\"Va2\",\"Vb2\")
rownames(out) <- 1:nrow(out)
> out
    V1 V2 Va1 Vb1 Va2 Vb2
1    A  A   1   3   1   3
2    A  B   1   3   2   2
3    A  C   1   3   3   1
4    B  A   2   2   1   3
5    B  B   2   2   2   2
6    B  C   2   2   3   1
您将必须手动重命名列,因为您将获得多个具有相同名称的列。尽管从技术上讲,它可以在数据帧中使用,但以后可能会引起麻烦。您可以使用以下方法自动执行此操作:
names(out) <- 
    c(\"V1\",\"V2\",
      sapply(names(df2)[2:3],paste,1:2,sep=\"\")
    )
编辑:对于大数据框,转换为矩阵会产生另一个巨大差异。必须注意不同变量类型的内在变化。加速是由于事实,即cbind和merge需要花费大量时间才能找出每个变量的正确类型。 具有以下数据和功能:
n <- 1e5
df1 <- data.frame(V1 = rep(LETTERS,each=n),V2 = rep(LETTERS,n),
        stringsAsFactors=FALSE)
df2 <- data.frame(V1=LETTERS,Va=1:26,Vb=26:1,stringsAsFactors=FALSE)

fast_JM <- function(df1,df2){
  out <- cbind(
    as.matrix(df2[,-1])[match(df1$V1,df2$V1),],
    as.matrix(df2[,-1])[match(df1$V2,df2$V1),]
  )
  out <- as.data.frame(out)
  names(out) <- sapply(names(df2)[2:3],paste,1:2,sep=\"\")
  out$V1 <- df1$V1
  out$V2 <- df1$V2
  out
}

slow_JM <- function(df1,df2){
  out <- cbind(df1,
    df2[match(df1$V1,df2$V1),-1],
    df2[match(df1$V2,df2$V1),-1]
  )
  names(out)[3:6] <- c(\"Va1\",\"Vb1\",\"Va2\",\"Vb2\")
  out
}


double_merge <- function(df1,df2){
  merge(merge(df1, df2), df2, by.x = \"V2\", by.y = \"V1\", suffixes = c(\"1\", \"2\"))
} 基准测试变为:
require(rbenchmark)
benchmark(fast_JM(df1,df2),slow_JM(df1,df2),double_merge(df1,df2),
      replications=1,columns=c(\"test\",\"elapsed\",\"relative\"),order=\"relative\")

                    test elapsed relative
1      fast_JM(df1, df2)    0.89  1.00000
2      slow_JM(df1, df2)   12.54 14.08989
3 double_merge(df1, df2)   42.50 47.75281
因此,与双重合并相比,速度提高了40倍以上,与使用数据帧相比,速度提高了10倍以上。     
您可以两次使用
merge()
得到想要的东西。默认情况下,“ 10”查找要加入的通用列名。在第二个合并中,我们将指定要合并的列:
df1 <- data.frame(V1 = c(\'A\', \'A\', \'A\', \'B\', \'B\', \'B\'), V2 = c(\'A\', \'B\', \'C\', \'A\', \'B\', \'C\'))
df2 <- data.frame(V1 = c(\'A\', \'B\', \'C\', \'D\'), Va = c(12, 15, 321, 54), Vb = c(23, 53, 543, 325))

merge(merge(df1, df2), df2, by.x = \"V2\", by.y = \"V1\", suffixes = c(\"1\", \"2\"))
    
我认为Hadley Wickham的dplyr软件包提供了一些很棒的工具来组合数据框。这是到达同一地点的另一种方式。
df1 <- data.frame(
  V1 = rep(LETTERS[1:2], each = 3L),
  V2 = rep.int(LETTERS[1:3], 2L)
)
dfr2 <- data.frame(
  V1 = LETTERS[1:4],
  Va = c(12, 15, 312, 54),
  Vb = c(23, 53, 543, 325)
)

##necessary libraries
library(magrittr, dplyr)
现在,使用
dplyr
包中的
left_join()
rename()
函数以及
magrittr
包中的管道运算符,我认为您可以节省很多击键。
df3 <- df1 %>% #pipe operator (%>%) is from magrittr package
  dplyr::left_join(dfr2, c(\'V1\'=\"V1\")) %>% #merge once
  dplyr::rename(Va1 = Va, Vb1 = Vb) %>%  #rename columns
  dplyr::left_join(dfr2, c(\'V2\'=\"V1\")) %>% #merge on different column
  dplyr::rename(Va2 = Va, Vb2 = Vb) #rename again
也可以使用一次合并而不是两次合并来完成此操作,但是我想看看每一步都在进行什么。
> print(df3)
  V1 V2 Va1 Vb1 Va2 Vb2
1  A  A  12  23  12  23
2  A  B  12  23  15  53
3  A  C  12  23 312 543
4  B  A  15  53  12  23
5  B  B  15  53  15  53
6  B  C  15  53 312 543
    

要回复问题请先登录注册