我有一个如下所示的数据框:
group1<-c(rep(1,12))
group2<-c(rep('Low',6), rep('High',6))
var <-c(1:6,1:6)
var1 <-c(2:13)
var2 <-c(20:31)
df1<-data.frame(group1,group2,var,var1,var2)
group1<-c(rep(2,12))
group2<-c(rep('Low',6), rep('High',6))
var <-c(1:6,1:6)
var1 <-c(2:13)
var2 <-c(20:31)
df2<-data.frame(group1,group2,var,var1,var2)
df<-rbind(df1,df2)
group1 group2 var var1 var2
1 1 Low 1 2 20
2 1 Low 2 3 21
3 1 Low 3 4 22
4 1 Low 4 5 23
5 1 Low 5 6 24
6 1 Low 6 7 25
7 1 High 1 8 26
8 1 High 2 9 27
9 1 High 3 10 28
10 1 High 4 11 29
11 1 High 5 12 30
12 1 High 6 13 31
13 2 Low 1 2 20
14 2 Low 2 3 21
15 2 Low 3 4 22
16 2 Low 4 5 23
17 2 Low 5 6 24
18 2 Low 6 7 25
19 2 High 1 8 26
20 2 High 2 9 27
21 2 High 3 10 28
22 2 High 4 11 29
23 2 High 5 12 30
24 2 High 6 13 31
我想以下列方式规范化我的列。对于group1
和group2
的每个组合,我想用它们的第一个元素划分var1
和var1
列。这允许我跨感兴趣的列构建共同的比例/索引。例如,看看group1=1
和group2=low
的组合,var1
的相关元素应该分别转换为2/2,3/2,4/2,5/2,6/2,7/2
,因为group1=1
和group2=High
的组合应该是8/8,9/8,10/8,11/8,12/8,13/8
等等。
我想对var1
和var2
进行上述转换。预期输出应如下所示:
group1 group2 var var1 var2 var1_tra var2_tra
1 1 Low 1 2 20 1.000 1.000000
2 1 Low 2 3 21 1.500 1.050000
3 1 Low 3 4 22 2.000 1.100000
4 1 Low 4 5 23 2.500 1.150000
5 1 Low 5 6 24 3.000 1.200000
6 1 Low 6 7 25 3.500 1.250000
7 1 High 1 8 26 1.000 1.000000
8 1 High 2 9 27 1.125 1.038462
9 1 High 3 10 28 1.250 1.076923
10 1 High 4 11 29 1.375 1.115385
11 1 High 5 12 30 1.500 1.153846
12 1 High 6 13 31 1.625 1.192308
13 2 Low 1 2 20 1.000 1.000000
14 2 Low 2 3 21 1.500 1.050000
15 2 Low 3 4 22 2.000 1.100000
16 2 Low 4 5 23 2.500 1.150000
17 2 Low 5 6 24 3.000 1.200000
18 2 Low 6 7 25 3.500 1.250000
19 2 High 1 8 26 1.000 1.000000
20 2 High 2 9 27 1.125 1.038462
21 2 High 3 10 28 1.250 1.076923
22 2 High 4 11 29 1.375 1.115385
23 2 High 5 12 30 1.500 1.153846
24 2 High 6 13 31 1.625 1.192308
注意:数字可以是任何东西,通常是正实数,因为我的数据帧非常大,不能提前知道为了执行这样的转换,我想要分割的元素是什么。
在按“group1”,“group2”分组后,使用mutate_at
对该列的first
值选择的列进行除法
library(dplyr)
df %>%
group_by(group1, group2) %>%
mutate_at(vars(var1, var2), list(tra = ~ ./first(.)))
# A tibble: 24 x 7
# Groups: group1, group2 [4]
# group1 group2 var var1 var2 var1_tra var2_tra
# <dbl> <fct> <int> <int> <int> <dbl> <dbl>
# 1 1 Low 1 2 20 1 1
# 2 1 Low 2 3 21 1.5 1.05
# 3 1 Low 3 4 22 2 1.1
# 4 1 Low 4 5 23 2.5 1.15
# 5 1 Low 5 6 24 3 1.2
# 6 1 Low 6 7 25 3.5 1.25
# 7 1 High 1 8 26 1 1
# 8 1 High 2 9 27 1.12 1.04
# 9 1 High 3 10 28 1.25 1.08
#10 1 High 4 11 29 1.38 1.12
# … with 14 more rows
或者使用data.table
nm1 <- c("var1", "var2")
nm2 <- paste0(nm1, "_tra")
library(data.table)
setDT(df)[, (nm2) := lapply(.SD, function(x) x/first(x)),
by = .(group1, group2), .SDcols = nm1]
你也可以使用sqldf
喜欢以下内容:
result <- sqldf('select df.*, (df.var1 + 0.0) / scale.s_var1 as var1_tra, (df.var2 + 0.0) / scale.s_var2 as var2_tra
from df join
(select group1, group2, min(var1) as s_var1, min(var2) as s_var2
from df
group by group1, group2) as scale
on df.group1 = scale.group1 AND df.group2 = scale.group2
')
在上面的代码中,我们首先使用以下查询找到每个组的var1
和var2
的最小值:
select group1, group2, min(var1) as s_var1, min(var2) as s_var2
from df
group by group1, group2
并将其用作嵌套查询并与df
和group1
的值相等的原始数据框group2
连接。