Со следующими данными ...purrr петля через колонки одного dataframe и условно заменить значения из другого dataframe
library(tidyverse)
df_fac <- data_frame("author_1" = c("Ted", "Fred", NA, "Jim", "Tim"),
"role_1" = c("Faculty", "Faculty", "Staff", "Faculty", "Faculty"),
"author_2" = c(NA, "Will", NA, "Bill", NA),
"role_2" = c("Staff", "Faculty", "Staff", "Faculty", "Staff"))
df_all <- data_frame("author_1" = c("Ted", "Fred", "Simon", "Jim", "Tim"),
"role_1" = c("Faculty", "Faculty", "Staff", "Faculty", "Faculty"),
"author_2" = c("Sam", "Will", "Noah", "Bill", "Luther"),
"role_2" = c("Staff", "Faculty", "Staff", "Faculty", "Staff"))
Если «автор» столбцы в df_fac
являются NA
, я хотел бы, чтобы они наполняются в с соответствующим значением столбца от df_all
с использованием функции map
от purrr
. Это то, что я в настоящее время обойтись без цикла:
df_test <- df_fac %>%
mutate(`author_1` = ifelse(is.na(`author_1`), df_all$`author_1`, `author_1`)) %>%
mutate(`author_2` = ifelse(is.na(`author_2`), df_all$`author_2`, `author_2`))
С map_df
я могу сделать это Перебор столбцов в df_fac
, но не в df_all
(Как вы можете видеть, что только автор колонки 1).
df_test <- map_df(select(df_fac, matches("author.\\d$")), ~ {
ifelse(is.na(.), df_all$`author_1`, .)
})
Есть ли способ иметь map_df
перебрать select(df_all, matches("author.\\d$"))
в то время как он перебирает select(df_fac, matches("author.\\d$"))
?
В примере с игрушкой df_test
должен иметь одинаковые столбцы и значения автора как df_all
. Я пробовал:
df_test <- map_df(1:length(select(df_fac, matches("author.\\d$"))), ~ {
ifelse(is.na(select(df_fac, matches("author.\\d$"))[.]),
select(df_all, matches("author.\\d$"))[.],
select(df_fac, matches("author.\\d$"))[.])
})
Броски Error in bind_rows_(x, .id) : not compatible with STRSXP
df_test <- pmap_chr(list(is.na(select(df_fac, matches("author.\\d$"))),
select(df_all, matches("author.\\d$")),
select(df_fac, matches("author.\\d$"))),
ifelse)
Броски Error: Element 2 has length 2, not 1 or 10.
Мне нужно использовать функцию matches
как фактические данные, имеет много авторских колонок, смешанных с аналогичными именами переменных. Я могу уточнить, если это не ясно. Спасибо.
В вашем примере, похоже, вы хотите, чтобы ваш вывод 'df_test' был идентичен' df_all'. Не могли бы вы улучшить его, чтобы лучше отражать ваши реальные данные и в чем проблема? Также: 'map' отлично, но уверены ли вы, что это соответствует вашим потребностям? Может быть, '* _join()' или что-то еще более подходит –
@apom Блок кода с вызовами '' mutate' именно то, что я пытаюсь сделать, но используя цикл. В реальных данных есть столбцы и значения в 'df_fac', которые не находятся в' df_all' и наоборот, поэтому мой пример выше, чтобы принести отсутствующие имена авторов. На самом деле нет никакой проблемы с тем, как я это делаю сейчас, это всего лишь много повторяющихся кодов (я делаю то же самое с несколькими другими переменными, которые заканчиваются примерно 24 очень похожими вызовами 'mutate'). – Tunn
Хорошо, еще один вопрос: можем ли мы с уверенностью предположить, что 'df_fac' и' df_all' упорядочены одинаково? Если мы каким-то образом 'cbind()' их, будут ли их строки всегда соответствовать? Или есть переменная, к которой можно присоединиться? –