Сопоставление столбцов в двух фреймах данных с заданным условием для столбца в R - PullRequest
0 голосов
/ 03 ноября 2018

У меня есть два кадра данных. E.g.:

df1 <- data.frame(actor = c("Angel","David","Adah","Sophia"),
                  gender=c("Unknown","male","Unknown","female"),
                  others= c("some","other","info","a"),
                  stringsAsFactors = FALSE)

   actor    gender   others
1  Angel    Unknown  some
2  David    Male     other
3  Adah     Unknown  info
4  Sophia   female   a

df2 <- data.frame(names = c("Miguel","Angel","David","Sophia"),
                  gender=c("male","male","male","female"),
                  stringsAsFactors = FALSE)

   names    gender
1  Miguel   male
2  Angel    male
3  David    male
4  Sophia   female

И я хочу дополнить "Неизвестные" роды в df1 df2. Я пытался сделать:

df1$gender[df1$gender == "Unknown"] <- df2$gender[ df2$names %in% df1$actor[df1$gender == "Unknown"]]

Но результат был не в правильном порядке, хотя число мужчин или женщин было правильным.

Итак, я хочу получить результат:

   actor    gender           others
1  Angel    male             some
2  David    male             other
3  Adah     Unknown (or NA)  info
4  Sophia   female           a

Ответы [ 3 ]

0 голосов
/ 03 ноября 2018

Заполнение пропущенных данных - хороший вариант использования для dplyr::coalesce. В этом случае это не является строго необходимым, но если у вас есть несколько таблиц с неполной информацией, это может пригодиться!

library(dplyr)

df1 <- 
  data.frame(
    actor  = c("Angel","David","Adah","Sophia"),
    gender =c("Unknown","male","Unknown","female"),
    others = c("some","other","info","a"),
    stringsAsFactors = FALSE
  )

df2 <- 
  data.frame(
    names  = c("Miguel","Angel","David","Sophia"),
    gender = c("male","male","male","female"),
    stringsAsFactors = FALSE
  )

# Fix encoding of "Unknown" to NA
df1$gender[df1$gender == 'Unknown']  <- NA

# Perform a left join by matching actor to names
# then coalesce the gender columns with preference for
# gender from df1.
# Then select your desired columns
left_join(df1, df2, by = c('actor' = 'names')) %>%
  mutate(gender = coalesce(gender.x, gender.y)) %>%
  select(actor, gender, others)

#    actor gender others
# 1  Angel   male   some
# 2  David   male  other
# 3   Adah   <NA>   info
# 4 Sophia female      a
0 голосов
/ 26 февраля 2019

Мы могли бы использовать safe_left_join из моего пакета safejoin , и разрешить конфликт столбцов, используя coalesce

# devtools::install_github("moodymudskipper/safejoin")
library(safejoin)
library(dplyr)

df1$gender[df1$gender == "Unknown"] <- NA
safe_left_join(df1, df2, by = c(actor = "names"), conflict = coalesce)
#    actor gender others
# 1  Angel   male   some
# 2  David   male  other
# 3   Adah   <NA>   info
# 4 Sophia female      a
0 голосов
/ 03 ноября 2018

Рассмотрим левое объединение merge двух фреймов данных с ifelse для обновления пол с последующим переупорядочением строк. В частности, ключ добавляется к первому фрейму данных в качестве вспомогательного столбца для заказа после merge.

# MERGE AFTER ADD key COLUMN TO df1 AND RENAME COLUMNS IN df2
mdf <- merge(transform(df1, key=seq(nrow(df1))), setNames(df2, c('actor','gender')),
             by='actor', all.x=TRUE, suffixes=c('','_'))
mdf$gender <- ifelse(is.na(mdf$gender_), mdf$gender, mdf$gender_)

# RE-ORDER ROWS BY, THEN REMOVE HELPER COLUMNS
mdf <- with(mdf, transform(mdf[order(key),], key=NULL, gender_=NULL))
row.names(mdf) <- NULL

mdf
#    actor  gender others
# 1  Angel    male   some
# 2  David    male  other
# 3   Adah Unknown   info
# 4 Sophia  female      a
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...