Объединить фрейм данных с условиями - PullRequest
0 голосов
/ 20 октября 2018

ниже - мои фреймы данных.

df1<-data.frame(month=c("march", "april"), apple=c(1,NA), peach=c(10,NA))
df2<-data.frame(month=c("march", "april"), apple=c(5,3), peach=c(NA,NA))

Я хочу, чтобы R сделал следующее:

  • Если значения ячеек присутствуют в обоих фреймах данных - (значение ячейки из df1) - (значение ячейки из df2)
  • Если значение ячейки из df1 отсутствует, но присутствует значение ячейки из df2 - напишите «first»
  • Если значение ячейки из df2 отсутствует, но значение ячейки изприсутствует df1 - напишите «second»
  • Если оба отсутствуют - напишите «both»

вот так:

enter image description here

Я пытался df1-df2, но места, где каждый из фреймов данных имел NA, были заполнены NA.Затем я попытался использовать функцию «Применить», но не смог понять, как это сделать ...

Не могли бы вы помочь мне с этим?

Ответы [ 2 ]

0 голосов
/ 20 октября 2018

@ Комментарий Шри абсолютно правдив: не ожидайте, что значение -4 будет числом, когда вы вернете кадр (на самом деле это будет "-4". Я собираюсь предположить, что должно произойти что-то ещевот, так вот решение того, что, по вашему мнению, вам нужно: -)

func <- function(a,b) {
  naa <- is.na(a)
  nab <- is.na(b)
  ifelse(naa,
         ifelse(nab, "both", "first"),
         ifelse(nab, "second", a-b))
}
mapply(func, df1[2:3], df2[2:3], SIMPLIFY=FALSE)
# $apple
# [1] "-4"    "first"
# $peach
# [1] "second" "both"  

Я не всегда доволен вложенным ifelse, но это не так уж далеко.Это может быть лучшей возможностью для dplyr::case_when, возможно, упражнением на потом.

Это может быть применено непосредственно к кадру, например:

df0 <- df1
df0[2:3] <- mapply(func, df1[2:3], df2[2:3], SIMPLIFY=FALSE)
df0
#   month apple  peach
# 1 march    -4 second
# 2 april first   both

Но (снова) как@ Шри сказал ранее, у тебя там не будет чисел:

str(df0)
# 'data.frame': 2 obs. of  3 variables:
#  $ month: Factor w/ 2 levels "april","march": 2 1
#  $ apple: chr  "-4" "first"
#  $ peach: chr  "second" "both"
0 голосов
/ 20 октября 2018

Я думаю, что-то вроде этого - то, что вы ищете

```{r}
df1<-data.frame(month=c("march", "april"), apple=c(1,NA), peach=c(10,NA))
df2<-data.frame(month=c("march", "april"), apple=c(5,3), peach=c(NA,NA))

myconditions <- function(a, b) {
  if (is.na(a)) {
    if (is.na(b)) {
      "both"
    } else {
      "first"
    }
  } else {
    if(is.na(b)) {
      "second"
    } else {
      a - b
    }
  }
}

df1$apple[match(df2$month,df1$month)] <- mapply(myconditions,df1$apple,df2$apple)
df1$peach[match(df2$month,df1$month)] <- mapply(myconditions,df1$peach,df2$peach)

```

Полученная матрица будет в df1.

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

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

...