如何加入ColumnA =(ColumnB-1)

时间:2019-07-03 12:47:00

标签: r

我正在尝试加入两个数据框。连接的条件不是ColumnA = ColumnB *,而是ColumnA = ColumnB * Function。 通过功能合并,我看不到如何处理

有个例子,

df1 <- data.frame(ID=c(5,4,3,2), CASE=c("A","B","C","D"))
df2 <- data.frame(ID=c(6,5,4,3), RESULT=c("ResultA","ResultB","ResultC","ResultD"))

我想将df1和df2与 df1 $ ID = df2 $ ID-1 之类的东西加入,以得到结果:

df_result<- data.frame(ID_df1=c(5,4,3,2), CASE=c("A","B","C","D"), RESULT=c("Result5","Result4","Result3","Result2"))

我试图删除连接中的引号,但是它不起作用:

df_result <- merge ( x = df1, y = df2, by.x = ID , by.y = ID - 1 , all.x = TRUE)

有人可以帮助我吗? :)

谢谢!

2 个答案:

答案 0 :(得分:0)

一种tidyverse解决方案可以重现您的预期输出,

library(tidyverse)
left_join(df1, df2 %>% mutate(ID = ID - 1)) %>%
    mutate(RESULT = str_replace(RESULT, "^(.+)[A-Z]$", paste0("\\1", ID)))
#Joining, by = "ID"
#  ID CASE  RESULT
#1  5    A Result5
#2  4    B Result4
#3  3    C Result3
#4  2    D Result2

说明:如果您只想通过IDID - 1合并,则简单

left_join(df1, df2 %>% mutate(ID = ID - 1))
#  ID CASE  RESULT
#1  5    A ResultA
#2  4    B ResultB
#3  3    C ResultC
#4  2    D ResultD

就足够了。额外的mutate会根据您的预期输出来重命名RESULT


否则基本的R选项将从

开始
merge(df1, transform(df2, ID = ID - 1), by = "ID")
#  ID CASE  RESULT
#1  2    D ResultD
#2  3    C ResultC
#3  4    B ResultB
#4  5    A ResultA

,包括重命名RESULT

transform(
    merge(df1, transform(df2, ID = ID - 1), by = "ID"),
    RESULT = paste0(substr(RESULT, 1, nchar(as.character(RESULT)) - 1), ID))
#  ID CASE  RESULT
#1  2    D Result2
#2  3    C Result3
#3  4    B Result4
#4  5    A Result5

再现您的预期输出(行顺序略有不同)。

答案 1 :(得分:0)

使用SQL这样的联接很容易。在这种情况下,df1的每一行在df2中都有一个匹配项,因此我们可以省略left关键字,但是如果df1中有行而在{{1}中没有匹配项} df2将确保保留它们。

left

library(sqldf) sqldf("select a.*, substr(b.RESULT, 1, length(b.RESULT)-1) || cast(a.ID as integer) as RESULT from df1 as a left join df2 as b on a.id = b.id - 1") 子句可以具有与on和/或and相关的复杂条件,以防您需要更复杂的条件。

或者在SQL中进行联接,然后分别对or进行转换。

RESULT