如何使用purrr将函数应用于列对?

时间:2018-01-13 05:01:04

标签: r purrr

我有以下数据帧来自与dplyr的连接:

data_frame(id=1:4, a.x = c(1, NA, 3, 4), a.y = c(1, 2, 3, 4), b.x = c(NA, NA, 3, NA), b.y = c(2, 2, NA, 4)) 
# A tibble: 4 x 5
     id   a.x   a.y   b.x   b.y
  <int> <dbl> <dbl> <dbl> <dbl>
1     1     1     1    NA     2
2     2    NA     2    NA     2
3     3     3     3     3    NA
4     4     4     4    NA     4

我想将以.x结尾的列中的所有NA替换为以.y结尾的列中的值。最后,我想实现这个目标:

# A tibble: 4 x 5
     id   a.x   a.y   b.x   b.y
  <int> <dbl> <dbl> <dbl> <dbl>
1     1     1     1     2     2
2     2     2     2     2     2
3     3     3     3     3    NA
4     4     4     4     4     4

我尝试使用这样的purrr:

data_frame(id=1:4, a.x = c(1, NA, 3, 4), a.y = c(1, 2, 3, 4), b.x = c(NA, NA, 3, NA), b.y = c(2, 2, NA, 4)) %>%
  map2_dfr(.x = ends_with('.y'), .y = ends_with('.x'), ~ case_when(is.na(.x) ~ .y,
                                                                   TRUE ~ .x))

哪个错了。文档对我来说有点混乱,我认为这里的问题是.x需要一个向量,但是如何传递一列列呢?

1 个答案:

答案 0 :(得分:2)

解决方案。我们可以gatherseparate.arrange列,fill值朝上,unite列,最后{ {1}}数据框到原始结构。

spread

或者,如果数据框中列的顺序良好,我们可以使用包中的library(tidyverse) dat2 <- dat %>% gather(Column, Value, -id) %>% separate(Column, into = c("Col1", "Col2")) %>% arrange(id, Col1, Col2) %>% group_by(id, Col1) %>% fill(Value, .direction = "up") %>% unite(Column, Col1, Col2, sep = ".") %>% spread(Column, Value) %>% ungroup() dat2 ## A tibble: 4 x 5 # id a.x a.y b.x b.y # * <int> <dbl> <dbl> <dbl> <dbl> # 1 1 1.00 1.00 2.00 2.00 # 2 2 2.00 2.00 2.00 2.00 # 3 3 3.00 3.00 3.00 NA # 4 4 4.00 4.00 4.00 4.00 函数,但请注意列类型可能会在处理后发生变化。 / p>

transpose

使用创建具有列名dat2 <- dat %>% data.table::transpose() %>% fill(everything(), .direction = 'up') %>% data.table::transpose() %>% setNames(names(dat)) dat2 # id a.x a.y b.x b.y # 1 1 1 1 2 2 # 2 2 2 2 2 2 # 3 3 3 3 3 NA # 4 4 4 4 4 4 “x”和“y”的子集的解决方案,然后将原始列替换为“x”。

ends_with

数据

dat_x <- dat %>% select(ends_with("x"))
dat_y <- dat %>% select(ends_with("y"))

dat[, grepl("x$", names(dat))] <- map2(dat_x, dat_y, ~ifelse(is.na(.x), .y, .x)) 
dat
# # A tibble: 4 x 5
#      id   a.x   a.y   b.x   b.y
#   <int> <dbl> <dbl> <dbl> <dbl>
# 1     1  1.00  1.00  2.00  2.00
# 2     2  2.00  2.00  2.00  2.00
# 3     3  3.00  3.00  3.00 NA   
# 4     4  4.00  4.00  4.00  4.00