Как присоединиться к ColumnA = (ColumnB - 1) - PullRequest
0 голосов
/ 03 июля 2019

Я пытаюсь объединить два кадра данных.Условием объединения является не 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 голосов
/ 03 июля 2019

Такое объединение легко сделать с помощью SQL.В этом случае каждая строка df1 имеет совпадение в df2, поэтому мы можем опустить ключевое слово left, но если бы в df1 были строки без совпадения в 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 и / или or в случае необходимости более сложных условий.

Поочередно выполняйте объединение вSQL, а затем преобразование RESULT отдельно.

s <- sqldf("select a.*, b.RESULT
  from df1 as a 
  left join df2 as b on a.id = b.id - 1")
transform(s, RESULT = paste0(sub(".$", "", RESULT), ID))
0 голосов
/ 03 июля 2019

A 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

Объяснение: Если вы хотите объединить только ID и ID - 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

воспроизведение ожидаемого результата (с немного другим порядком строк).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...