如何通过传递`sep`参数来对所有列应用split_rows()?

时间:2019-11-06 20:22:28

标签: r tidyr purrr

非常简单明了:我有一个数据框,其中需要根据;作为分隔符,将许多列中的值拆分为自己的行。

稍作阅读后,

df %>%
   Reduce(separate_rows_, x = colnames)

是有效的,但不能传递sep参数(因此它也由空格,逗号和其他非字母数字字符分隔)。

一个答案建议编写包含参数的函数的修改版本,但我无法正常工作:

Reduce(f = function(y) separate_rows_(sep = ";"), x = colnames)

我在做什么错了?

话虽如此,我的理想解决方案是整洁的解决方案,如果它更清洁(也许是map_dfr?);但显然任何解决方案都比没有解决方案要好:)。

以下是示例数据:

structure(list(q1 = c("1,2,3,4", "2,4"), q2 = c("a,b", "e,f"), 
q3 = c("c,d", "g,h,z")), row.names = 1:2, class = "data.frame")

预期输出:

structure(list(q1 = c("1", "1", "1", "1", "2", "2", "2", "2", 
"3", "3", "3", "3", "4", "4", "4", "4", "2", "2", "2", "2", "2", 
"2", "4", "4", "4", "4", "4", "4"), q2 = c("a", "a", "b", "b", 
"a", "a", "b", "b", "a", "a", "b", "b", "a", "a", "b", "b", "e", 
"e", "e", "f", "f", "f", "e", "e", "e", "f", "f", "f"), q3 = c("c", 
"d", "c", "d", "c", "d", "c", "d", "c", "d", "c", "d", "c", "d", 
"c", "d", "g", "h", "z", "g", "h", "z", "g", "h", "z", "g", "h", 
"z")), row.names = c(NA, -28L), class = "data.frame")

我要简化的过程不必像这样传递每个列名:

output <- test %>% 
  separate_rows(q1, sep = ",") %>% 
  separate_rows(q2, sep = ",") %>% 
  separate_rows(q3, sep = ",")  

1 个答案:

答案 0 :(得分:2)

您可以使用purrr::reduce,它将给定的函数.f应用于.init.x的第一个元素,然后将该函数应用于该函数和.x的第二个元素,依此类推,直到.x的所有元素都已使用。

.f参数公式中,.x是先前的输出(或第一次运行的.init),而.y是{{1}的给定元素} .x的参数。

reduce

如akrun注释中所述,这也可以使用下面的代码(相同的输出)在base R中完成

library(tidyverse)

reduce(.init = df, .x = names(df), .f = ~separate_rows(.x, .y, sep = ','))
# equiv to: reduce(.init = df, .x = names(df), .f = separate_rows, sep = ',')