我已经使用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)
pmap这是做类似事情的一种方法。pmap通过将每一行捕获为命名向量,可用于按行有效地处理数据帧;cols然后,您可以通过使用 来选择所需的列名称以进行索引["pastecols"]。
大多数匿名函数语法并不是tidyverse什么东西,而只是基本的 R 东西。要浏览它:
.l参数pmap_chr。请记住,数据框是列的列表!...参数c(...)。基本上,我们将数据帧的每一行调用为函数的参数;nowrow是包含该行的命名向量。请注意,如果您有列表列,这将会破坏,(但是这里的很多其他东西也会破坏,所以我假设没有......)row我们可以从 中获取我们想要的值row["pastecols"],但我们需要将(比如说)变成"B, C"来c("A", "B", "C")做到这一点。下一行只是添加"A",用 替换缺失值"A",如果有的话分成几部分,然后索引回到列表中。该部分就是您在管道链中的[[做法,它是运算符的前缀形式。list[[1]]"您需要这个,因为str_split返回一个列表,而我们只需要向量。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 日创建。