过滤后,向dataframe添加包含值的新列

时间:2018-01-19 09:08:28

标签: r dplyr

这是我发现自己经常做的事情,所以我想知道是否有更快的/“R”方式来做这件事:

A:
      a     b
  <dbl> <lgl>
1     1 FALSE
2     2  TRUE
3     3  TRUE
4     4 FALSE

B:
      c     d eeyyccc
  <dbl> <chr>   <dbl>
1    11    AA      55
2    22    BB      66

我想得到的是:将B合并到子集A[A$b==T,],用NA填充所有未知值。

      a     b     c     d eeyyccc
  <dbl> <lgl> <dbl> <chr>   <dbl>
1     1 FALSE    NA   NA      NA
2     2  TRUE    11   AA      55
3     3  TRUE    22   BB      66
4     4 FALSE    NA   NA      NA

通过过滤和“动态”创建列,是否有快速的“R”方式?我不能明确地使用B的任何列名,因为我事先不知道它们是什么......

A <- tibble(a = c(1,2,3,4), b=c(F,T,T,F))
B <- tibble(c=c(11,22), d=c("AA", "BB"), eeyyccc=c(55,66))

是否有某些东西(在dplyr或基础R中)允许我在一行中执行此操作,例如像:

A[A$b==T,] <- cbind(A$b==T,B) # does not work

2 个答案:

答案 0 :(得分:3)

我们可以replace使用dplyr

library(dplyr)
A %>%
   mutate(c = replace(NA, b, B$c))
# A tibble: 4 x 3
#  a b         c
#  <dbl> <lgl> <dbl>
#1  1.00 F      NA  
#2  2.00 T      11.0
#3  3.00 T      22.0
#4  4.00 F      NA  

base R

transform(A, c = replace(NA, b, B$c))

更新

使用更新的数据

library(purrr)
A[names(B)] <- map(B, ~ replace(NA, A$b, .x))
A
# A tibble: 4 x 5
#      a b         c d     eeyyccc  
#   <dbl> <lgl> <dbl> <chr>   <dbl>
#1  1.00 F      NA   <NA>     NA  
#2  2.00 T      11.0 AA       55.0
#3  3.00 T      22.0 BB       66.0
#4  4.00 F      NA   <NA>     NA  

base R

A[names(B)] <- lapply(B, function(x) replace(NA, A$b, x))

答案 1 :(得分:2)

这是一个选项。关键是创建一个合并变量(M),然后进行合并。无需在B中指定任何列名。

library(dplyr)
A %>%
  mutate(M = ifelse(b, cumsum(b), NA)) %>%
  left_join(B %>% mutate(M = 1:n()), by = "M") %>%
  select(-M)
# # A tibble: 4 x 5
#       a b         c d     eeyyccc
#   <dbl> <lgl> <dbl> <chr>   <dbl>
# 1  1.00 F      NA   NA       NA  
# 2  2.00 T      11.0 AA       55.0
# 3  3.00 T      22.0 BB       66.0
# 4  4.00 F      NA   NA       NA