dplyr通过评估查找单元格值来改变特定列

tcu*_*son 5 eval r dplyr

我已经使用quosures,symbols和evaluation来探索各种选项,但我似乎无法获得正确的语法.这是一个示例数据帧.

data.frame("A" = letters[1:4], "B" = letters[26:23], "C" = letters[c(1,3,5,7)], "D" = letters[c(2,4,6,8)], "pastecols" = c("B, C","B, D", "B, C, D", NA))
  A B C D pastecols
1 a z a b      B, C
2 b y c d      B, D
3 c x e f   B, C, D
4 d w g h      <NA>
Run Code Online (Sandbox Code Playgroud)

现在假设我想根据pastecols中的查找字符串粘贴来自不同列的值,并且我总是希望包含列A.这是我想要的结果:

  A B C D pastecols  result
1 a z a b      B, C   a z a
2 b y c d      B, D   b y d
3 c x e f   B, C, D c x e f
4 d w g h      <NA>       d
Run Code Online (Sandbox Code Playgroud)

理想情况下,这可以在dplyr中完成.这是我得到的最接近的:

x %>% mutate(result = lapply(lapply(str_split(pastecols, ", "), c, "A"), na.omit))
  A B C D pastecols     result
1 a z a b      B, C    B, C, A
2 b y c d      B, D    B, D, A
3 c x e f   B, C, D B, C, D, A
4 d w g h      <NA>          A
Run Code Online (Sandbox Code Playgroud)

Cal*_*You 2

pmap这是做类似事情的一种方法。pmap通过将每一行捕获为命名向量,可用于按行有效地处理数据帧;cols然后,您可以通过使用 来选择所需的列名称以进行索引["pastecols"]

大多数匿名函数语法并不是tidyverse什么东西,而只是基本的 R 东西。要浏览它:

  1. 将数据帧作为列表传递给.l参数pmap_chr。请记住,数据框是列的列表!
  2. 捕获所有...参数c(...)。基本上,我们将数据帧的每一行调用为函数的参数;nowrow是包含该行的命名向量。请注意,如果您有列表列,这将会破坏,(但是这里的很多其他东西也会破坏,所以我假设没有......)
  3. row我们可以从 中获取我们想要的值row["pastecols"],但我们需要将(比如说)变成"B, C"c("A", "B", "C")做到这一点。下一行只是添加"A",用 替换缺失值"A",如果有的话分成几部分,然后索引回到列表中。该部分就是您在管道链中的[[做法,它是运算符的前缀形式。list[[1]]"您需要这个,因为str_split返回一个列表,而我们只需要向量。
  4. 使用此cols向量获取所需的值row并将其返回,折叠为长度为 1 的字符向量!
library(tidyverse)
tbl <- tibble("A" = letters[1:4], "B" = letters[26:23], "C" = letters[c(1,3,5,7)], "D" = letters[c(2,4,6,8)], "pastecols" = c("B, C","B, D", "B, C, D", NA))

tbl %>%
  mutate(result = pmap_chr(
    .l = .,
    .f = function(...){
      row <-  c(...)
      cols <- row["pastecols"] %>% str_c("A, ", .) %>% replace_na("A") %>% str_split(", ") %>% `[[`(1)
      vals <- row[cols] %>% str_c(collapse = ", ")
      return(vals)
    }
  ))
#> # A tibble: 4 x 6
#>   A     B     C     D     pastecols result    
#>   <chr> <chr> <chr> <chr> <chr>     <chr>     
#> 1 a     z     a     b     B, C      a, z, a   
#> 2 b     y     c     d     B, D      b, y, d   
#> 3 c     x     e     f     B, C, D   c, x, e, f
#> 4 d     w     g     h     <NA>      d
Run Code Online (Sandbox Code Playgroud)

由reprex 包(v0.2.0)于 2018 年 12 月 3 日创建。