在R中用dplyr划分多列

Divide multiple columns with dplyr in R

我的数据框看起来像这样,但我有数百列

t1 <- c(11,2,3,4)
t2 <- c(10,2,3,4)
total1 <- c(8,2,3,4)
total2 <- c(4,6,3,4)
test <- data.frame(t1,t2,total1,total2)
  t1 t2 total1 total2
1 11 10      8      4
2  2  2      2      6
3  3  3      3      3
4  4  4      4      4

我想划分 t1/total2 并创建一个名为 freq1 的新列 然后 t2/total2 并创建一个名为 freq2 的新列。我想做数百个 列数。

我希望我的数据看起来像这样

    t1 t2 total1 total2 freq1 freq2
1   11 10    8      4    1.37 2.5
2   2  2     2      6    1.    0.33
3   3  3     3      3.   1.    1
4   4  4     4      4.   1.    1

我就是这样工作的

mutate(freq1= t1/total1)

但是这是有问题的。我不能对所有列都这样做。

这是一个基本的 R 选项

cbind(
  test,
  lapply(
    split.default(
      test,
      paste0("freq", gsub("\D", "", names(test)))
    ),
    Reduce,
    f = "/"
  )
)

这给出了

  t1 t2 total1 total2 freq1     freq2
1 11 10      8      4 1.375 2.5000000
2  2  2      2      6 1.000 0.3333333
3  3  3      3      3 1.000 1.0000000
4  4  4      4      4 1.000 1.0000000

一个甚至不需要正则表达式的很好的 Base R 解决方案如下

df <- sapply(1:(ncol(test)/2), function(x) test[,x]/test[,x+(ncol(test)/2)])

我们的想法是,您有许多除以 2 的列,因此您可以只使用 sapply() 来划分列的组合。

我们可以分别对 't' 列和 'total' 的数据集进行子集化并划分它们(假设它们的顺序相同)

test[paste0('freq', 1:2)] <- test[1:2]/test[3:4]

使用dplyr您可以将两组列聚集在一起并分开,为列赋予新名称并将其绑定到原始数​​据。

library(dplyr)

bind_cols(test, 
          (test %>% select(matches('t\d+'))/
          test %>% select(matches('total\d+'))) %>%
            rename_with(~paste0('freq', seq_along(.)))
          )

#  t1 t2 total1 total2 freq1     freq2
#1 11 10      8      4 1.375 2.5000000
#2  2  2      2      6 1.000 0.3333333
#3  3  3      3      3 1.000 1.0000000
#4  4  4      4      4 1.000 1.0000000