заменить значение другим значением при совпадении - PullRequest
1 голос
/ 23 февраля 2020

Я пытаюсь использовать простую базовую функцию для отображения значений, если оба значения соответствуют двум фреймам данных, тогда старое значение должно остаться

df1 <- data.frame(a1 = c("b2","c2","abc2"),b1 = c("bb2","cc2","d2"))
> df1
    a1  b1
1   b2 bb2
2   c2 cc2
3 abc2  d2

df2 <- data.frame(a1 = c("sale","sale2","sale3"),b1 = c("b2","c2","d2"))
> df2
     a1 b1
1  sale b2
2 sale2 c2
3 sale3 d2


df2$b1 <- df1$b1[df1$b1 %in% df2$b1]

Желаемый результат:

     a1  b1
1  sale bb2
2 sale2 cc2
3 sale3  d2

Ответы [ 3 ]

1 голос
/ 23 февраля 2020

Не уверен, что это работает для вас, но гораздо проще, если вы используете пакет , как указано tjebo :

new_df <- df2 %>% mutate(b1 = case_when(b1 == df1$a1 ~ b1, b1 != df1$a1 ~ df1$a1))

Выходные данные

new_df
     a1   b1
1  sale   b2
2 sale2   c2
3 sale3 abc2

case_when - это способ dplyr создания if-else конструкции.

Примечание

Вам нужно иметь столбцы как угодно, кроме factors, чтобы это работало. Просто добавьте stringsAsFactors = F при формировании кадра данных, как показано ниже.

df2 <- data.frame(a1 = c("sale","sale2","sale3"),b1 = c("b2","c2","d2"),
                  stringsAsFactors = F)
1 голос
/ 23 февраля 2020

Вот базовое решение R, использующее merge + ifelse, т. Е.

dfout <- rev(within(merge(df1,df2,by.x = "a1",by.y = "b1",all.y = TRUE),
                    b1 <- ifelse(is.na(b1),as.character(a1),as.character(b1)))[-1])

, такое что

> dfout
   a1.y  b1
1  sale bb2
2 sale2 cc2
3 sale3  d2
1 голос
/ 23 февраля 2020

Предполагая, что вы имеете в виду совпадающие значения по позиции, здесь есть одно базовое решение R. Может быть все проще с такими пакетами, как data.table или dplyr, но, как правило, приятно сначала получить представление об использовании базы R.

Скорее всего, есть более приятные способы получить приведенный ниже результат. Я обычно не использую базу R для этого типа соединений

df1 <- data.frame(a1 = c("b2","c2","abc2"), b1 = c("bb2","cc2","d2"), stringsAsFactors = FALSE)
df2 <- data.frame(sale = c("sale","sale2","sale3"), b1 = c("b2","c2","d2"), stringsAsFactors = FALSE)

df1$sale <- df2$sale

joined <- merge(df2,df1,by = 'sale')
joined$new <- ifelse(joined$b1.x == joined$b1.y, joined$b1.x, joined$b1.y)
joined[,c(1,5)]
#>    sale new
#> 1  sale bb2
#> 2 sale2 cc2
#> 3 sale3  d2

Примечание. Я изменил имя во фреймах данных и изменил коэффициенты на символы, что делает возможным объединение.

Ключ в том, чтобы создать переменную, которая позволяет объединять / объединять (как бы вы ни хотели это вызывать). Я использую sale - это позволяет сопоставить по позиции.

обновление

Спасибо @WaltS за указание на гораздо более простой вариант. Поскольку сопоставление осуществляется по позиции, можно выполнить прямое присвоение столбца:

# date frames from above without factors!! 

df2$new <- ifelse(df2$b1 == df1$a1, df1$b1, df2$b1)

df2
#>    sale b1 new
#> 1  sale b2 bb2
#> 2 sale2 c2 cc2
#> 3 sale3 d2  d2

Создано в 2020-02-23 с помощью пакета Представить (v0.3.0)

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