purrr循环遍历一个数据帧的列,并有条件地替换另一个数据帧中的值

时间:2017-01-17 17:15:23

标签: r if-statement purrr

使用以下数据......

var FilterOptions = React.createClass({
changeOption: function(type, e) {
var val = e.target.value;
this.props.changeOption(val, type);
},

render: function() {

return (
  <div className="filter-options">
    <div className="filter-option">
      <select id="product" name="Product" value={this.props.product} onChange={this.changeOption.bind(this, 'product')}>
      <option value=''>Product</option>
      {this.props.productOptions.map(function(option) {
        return (<option key={option}  value={option}>{option}</option>)
      })}
      </select>
  </div>
  </div>
 );
 }
 });

如果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中进行迭代(正如您所看到的那样,只有作者列1)。

df_all

在迭代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.函数,因为实际数据中有很多作者列与类似的变量名混合在一起。我可以澄清这是否不清楚。谢谢。

1 个答案:

答案 0 :(得分:2)

您可以使用map2_df同时循环浏览两个列表。使用dplyr::coalsece将有助于替换缺失的值。我使用select来确保df_all中的列与df_fac中的列相同且顺序相同。

map2_df(df_fac, select(df_all, one_of(names(df_fac))), ~coalesce(.x, .y))

使用pmap同样的事情:

pmap_df(list(df_fac, select(df_all, one_of(names(df_fac)))), coalesce)

您可以将ifelsemap2一起使用,并使用公式表示法来引用您正在使用的两个不同列表。

map2_df(df_fac, select(df_all, one_of(names(df_fac))), 
       ~ifelse(is.na(.x), .y, .x))