在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
我的数据框看起来像这样,但我有数百列
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