我有一个名为MyData
的数据集,如下所示
A B C D E
1 yellow X 0.8 52 0.4
2 yellow X 0.5 116 1.5
3 yellow X 0.4 23 0
4 yellow Z 0.6 46 0.6
5 yellow Y 0.2 230 3
6 green X 0.3 1500 19
7 green Y 0.1 15 0
我想将第一行和第二行分组,将E
的平均值除以D
的平均值,并将结果与阈值0.01
进行比较。 (例如:((0.4+1.5)/2)/((52+116)/2)=0.011309524
,将0.011309524
与阈值0.01
进行比较)。
(1)如果结果大于阈值0.01,那么我们说第一和第二行成功形成一个组号为1
的组。我们需要将组号A
,B
,C
,D
(第1行和第2行)的平均值和E
的平均值输出到名为的新数据集中MyData2
。然后从第3行和第4行分组再次开始,将计算结果与阈值0.01
进行比较。如果再次成功,我们会将组号2
分配给第3行第4行并将其输出到MyData2
。
MyData2
Group NO. A B C D E
1 1 yellow X 0.8 84 0.95
2 1 yellow X 0.5 84 0.95
(2)如果结果来自第1行和第2行小于阈值0.01
,我们说第一行和第二行无法形成一个组。然后我们需要将E
的平均值除以第1行,第2行和第3行的D
的平均值。(这意味着将前3行组合在一起并计算((0.4+1.5+0)/3)/((52+116+23)/3)
并进行比较它到阈值0.01
)...如果分组"成功",将组号1
分配给第1行,第2行和第3行,并将上述值输出到{{ 1}}。如果仍未能形成组,我们需要将MyData2
的平均值除以第1行,第2行,第3行和第4行的平均值E
,直到成功为止。
我想要的输出:
D
我的实际数据集大约有100行。
答案 0 :(得分:0)
这不漂亮。由于分组是动态的,我没有看到任何方法来避免这个问题的循环,虽然我喜欢看到有人成功。我使用一套名为tidyverse
的软件包来执行此操作。它的一个功能是管道运算符%>%
。如果你不熟悉它,它会从最后一个操作中获取输出并将其作为下一个操作的第一个参数插入。它允许我按顺序执行操作而不是嵌套它们。
MyData2 <- MyData %>%
mutate(
one = 1,
index0 = cumsum(one),
index = index0,
GroupNo = NA_integer_,
Group_mean_D = NA_real_,
Group_mean_E = NA_real_,
result = NA_real_,
keep = NA
)
i <- 1L
while (sum(is.na(MyData2$GroupNo)) > 0) {
working_data <- filter(MyData2, is.na(GroupNo))
working_data <- working_data %>%
mutate(
GroupNo = i,
index = cumsum(one),
Group_mean_D = cumsum(D) / index,
Group_mean_E = cumsum(E) / index,
result = Group_mean_E / Group_mean_D,
keep = result > 0.01 & index > 1
) %>%
filter(index <= which(keep)[1])
i <- i + 1
MyData2[working_data$index0,] <- working_data
}
# Clean-up
MyData2 <- MyData2 %>% select(GroupNo, A:C, Group_mean_D, Group_mean_E)