r语言 - 有条件地减去数据帧中的单元格



假设我有以下数据帧

df1 <- data.frame(cbind("Method" = c("A", "A", "A", "A", 
"B", "B", "B", "B", 
"C", "C", "C", "C"),
"Sub" = c(rep(1:4, 2), c(1, 2, 4, 3)),
"Value1" = c(1, 2, 3, 4, 0, 0, 0, 0, 1, 2, 3, 4),
"Value2" = c(-1, -2, -3, -4, 0, 0, 0, 0, -1, -2, -3, -4),
"Value3" = 1:12))
Method Sub Value1 Value2 Value3
1       A   1      1     -1      1
2       A   2      2     -2      2
3       A   3      3     -3      3
4       A   4      4     -4      4
5       B   1      0      0      5
6       B   2      0      0      6
7       B   3      0      0      7
8       B   4      0      0      8
9       C   1      1     -1      9
10      C   2      2     -2     10
11      C   4      3     -3     11
12      C   3      4     -4     12

我想通过减去Method == A观察到的值来改变Value1Value2。在本例中,期望的输出将是

Method Sub Value1 Value2 Value3
1       A   1      0      0      1
2       A   2      0      0      2
3       A   3      0      0      3
4       A   4      0      0      4
5       B   1     -1      1      5
6       B   2     -2      2      6
7       B   3     -3      3      7
8       B   4     -4      4      8
9       C   1      0      0      9
10      C   2      0      0     10
11      C   4     -1      1     11
12      C   3      1     -1     12

基本上,它看起来像从df1[5:8, 3:4]和df1[9:12, 3:4]中减去df1[1:4, 3:4],除了行必须匹配Sub(参见Method == C中的Sub顺序)。如何有效地实现这一点有什么帮助吗?

使用dplyr你可以做

library(dplyr)
df1 %>% 
group_by(Sub) %>% 
mutate(across(Value1:Value2, ~.x-.x[Method=="A"]))
#    Method   Sub Value1 Value2 Value3
#    <chr>  <dbl>  <dbl>  <dbl>  <int>
#  1 A          1      0      0      1
#  2 A          2      0      0      2
#  3 A          3      0      0      3
#  4 A          4      0      0      4
#  5 B          1     -1      1      5
#  6 B          2     -2      2      6
#  7 B          3     -3      3      7
#  8 B          4     -4      4      8
#  9 C          1      0      0      9
# 10 C          2      0      0     10
# 11 C          4     -1      1     11
# 12 C          3      1     -1     12

这将为每个Sub创建一个组,然后您可以提取方法的值==" a ">

您必须使用ifelse函数。它的工作原理就像Excel中的if函数

library(dplyr)
df2 <- df1 %>%
mutate(Value4 = ifelse(Method == "A", Value1 - Value2 , NA))

作为旁注,您可以更容易地构建您的DataFrame:

df1 <- data.frame(
Method = c("A", "A", "A", "A", 
"B", "B", "B", "B", 
"C", "C", "C", "C"),
Sub = c(rep(1:4, 2), c(1, 2, 4, 3)),
Value1 = c(1, 2, 3, 4, 0, 0, 0, 0, 1, 2, 3, 4),
Value2 = c(-1, -2, -3, -4, 0, 0, 0, 0, -1, -2, -3, -4),
Value3 = c(1:12)
)

最新更新