循环名称基于向量模式

Loop colnames basis a vector pattern

我希望根据向量过滤基本列名称,然后将它们绑定在一起。

这是我的数据框 -

df = data.frame("Applefor_yes" = 1:4,
                "Applefor_no" = 2:5,
                "Bananfor_yes" = 1:4,
                "Bananfor_no" = 2:5)

   Applefor_yes Applefor_no Bananfor_yes Bananfor_no
1            1           2            1           2
2            2           3            2           3
3            3           4            3           4
4            4           5            4           5

我希望输出看起来像这样。

     fruit yes no
1 Applefor   1  2
2 Applefor   2  3
3 Applefor   3  4
4 Applefor   4  5
5 Bananfor   1  2
6 Bananfor   2  3
7 Bananfor   3  4
8 Bananfor   4  5

简而言之,我想根据向量 c("Bananfor", "Applefor")

循环列名

这是一个基本的 R 解决方案

pat <- c("yes","no")
u <- data.frame(setNames(lapply(pat, function(x) unlist(subset(df,select = grep(x,names(df))))),pat))
dfout <- data.frame(fruit = gsub("_.*","",rownames(u)),u,row.names = NULL)

dfout <- do.call(rbind,
                 c(make.row.names = F,
                   Map(function(x) data.frame(fruit = gsub("_.*","",names(x)),
                                              setNames(x,gsub(".*_","",names(x)))),
                       split(unclass(df),gsub("(.*)_.*","\1",names(df))))))

这样

> dfout
     fruit yes no
1 Applefor   1  2
2 Applefor   2  3
3 Applefor   3  4
4 Applefor   4  5
5 Bananfor   1  2
6 Bananfor   2  3
7 Bananfor   3  4
8 Bananfor   4  5

我们可以使用 tidyr 中的 pivot_longer 指定 names_tonames_sep 参数。

tidyr::pivot_longer(df, cols = everything(),
                        names_to = c("fruit", ".value"), 
                        names_sep = "_")

#  fruit      yes    no
#  <chr>    <int> <int>
#1 Applefor     1     2
#2 Bananfor     1     2
#3 Applefor     2     3
#4 Bananfor     2     3
#5 Applefor     3     4
#6 Bananfor     3     4
#7 Applefor     4     5
#8 Bananfor     4     5