计算 R 中多个单独案例的单个案例中两个观察值之间的差异
Calculate difference between two observations in a single case for a number of separate cases in R
我有一个类似于下面的数据集。
Case <- c("A", "B", "C", "A", "B", "C", "A", "B", "C")
ObservationNumber <- c(1, 1, 1, 2, 2, 2, 3, 3, 3)
ObservedValue <- c(154, 152, 157, 173, 176, 171, 203, 205, 199)
我正在尝试创建一个新的数据框,其中一列是案例(A、B 或 C),第二列是从第一次观察到第三次观察的观察值变化。行数将是不同案例的数量(在上面的示例中为 3,但在实际数据集中为数百)。
有一些变通方法适用于示例数据,但我的真实数据是数百个案例,每个案例有 50 个观察值。因此,我需要一些不需要 (1) 为每个案例创建单独的数据集(例如通过过滤)来执行减法的方法,这是我能够想出的唯一方法拥有。
是否有人对此有任何其他想法?
**同样在示例中,行是按顺序排列的,但在真实数据集中它们不是。结果,我不能只占每组的第一行和最后一行;我需要在每组中获取具有最大值和最小值的行。下面的两个答案都很好地解决了这个问题。
Case <- c("A", "B", "C", "A", "B", "C", "A", "B", "C")
ObservationNumber <- c(1, 1, 1, 2, 2, 2, 3, 3, 3)
ObservedValue <- c(154, 152, 157, 173, 176, 171, 203, 205, 199)
mydat <- as.data.frame(cbind(Case, ObservationNumber, ObservedValue),stringsAsFactors = F)
mydat$ObservedValue <- as.numeric(mydat$ObservedValue)
result <- data.frame()
for(c in unique(mydat$Case)){
result <- rbind(result, data.frame(Case=c,Diff=
mydat$ObservedValue[mydat$Case==c & mydat$ObservationNumber == min(mydat$ObservationNumber)] -
mydat$ObservedValue[mydat$Case==c & mydat$ObservationNumber == max(mydat$ObservationNumber)]
))
}
result
Case Diff
1 A -49
2 B -53
3 C -42
我还用更大的数据集做了一个例子,以确保它仍然很快,它是:
Case <- c(rep("A",50), rep("B",50),rep("C",50))
ObservationNumber <- rep(seq(1,50),3)
ObservedValue <- runif(150)
mydat <- as.data.frame(cbind(Case, ObservationNumber, ObservedValue),stringsAsFactors = F)
mydat$ObservedValue <- as.numeric(mydat$ObservedValue)
result <- data.frame()
for(c in unique(mydat$Case)){
result <- rbind(result, data.frame(Case=c,Diff=
mydat$ObservedValue[mydat$Case==c & mydat$ObservationNumber == min(mydat$ObservationNumber)] -
mydat$ObservedValue[mydat$Case==c & mydat$ObservationNumber == max(mydat$ObservationNumber)]
))
}
...为了 100% 确定,我再次将其扩大到 4 个案例,每个案例有 500 个观察值(2000 行),它仍然在不到 1 秒的时间内完成:
Case <- c(rep("A",500), rep("B",500),rep("C",500), rep("D",500))
ObservationNumber <- rep(seq(1,500),4)
ObservedValue <- runif(2000)
mydat <- as.data.frame(cbind(Case, ObservationNumber, ObservedValue),stringsAsFactors = F)
mydat$ObservedValue <- as.numeric(mydat$ObservedValue)
result <- data.frame()
for(c in unique(mydat$Case)){
result <- rbind(result, data.frame(Case=c,Diff=
mydat$ObservedValue[mydat$Case==c & mydat$ObservationNumber == min(mydat$ObservationNumber)] -
mydat$ObservedValue[mydat$Case==c & mydat$ObservationNumber == max(mydat$ObservationNumber)]
))
}
我喜欢使用 dplyr
库来解决这些 grouping/summarising 问题:
library(dplyr)
df %>%
arrange(ObservationNumber) %>%
group_by(Case) %>%
summarise(diff = last(ObservedValue) - first(ObservedValue))
我有一个类似于下面的数据集。
Case <- c("A", "B", "C", "A", "B", "C", "A", "B", "C")
ObservationNumber <- c(1, 1, 1, 2, 2, 2, 3, 3, 3)
ObservedValue <- c(154, 152, 157, 173, 176, 171, 203, 205, 199)
我正在尝试创建一个新的数据框,其中一列是案例(A、B 或 C),第二列是从第一次观察到第三次观察的观察值变化。行数将是不同案例的数量(在上面的示例中为 3,但在实际数据集中为数百)。
有一些变通方法适用于示例数据,但我的真实数据是数百个案例,每个案例有 50 个观察值。因此,我需要一些不需要 (1) 为每个案例创建单独的数据集(例如通过过滤)来执行减法的方法,这是我能够想出的唯一方法拥有。
是否有人对此有任何其他想法?
**同样在示例中,行是按顺序排列的,但在真实数据集中它们不是。结果,我不能只占每组的第一行和最后一行;我需要在每组中获取具有最大值和最小值的行。下面的两个答案都很好地解决了这个问题。
Case <- c("A", "B", "C", "A", "B", "C", "A", "B", "C")
ObservationNumber <- c(1, 1, 1, 2, 2, 2, 3, 3, 3)
ObservedValue <- c(154, 152, 157, 173, 176, 171, 203, 205, 199)
mydat <- as.data.frame(cbind(Case, ObservationNumber, ObservedValue),stringsAsFactors = F)
mydat$ObservedValue <- as.numeric(mydat$ObservedValue)
result <- data.frame()
for(c in unique(mydat$Case)){
result <- rbind(result, data.frame(Case=c,Diff=
mydat$ObservedValue[mydat$Case==c & mydat$ObservationNumber == min(mydat$ObservationNumber)] -
mydat$ObservedValue[mydat$Case==c & mydat$ObservationNumber == max(mydat$ObservationNumber)]
))
}
result
Case Diff 1 A -49 2 B -53 3 C -42
我还用更大的数据集做了一个例子,以确保它仍然很快,它是:
Case <- c(rep("A",50), rep("B",50),rep("C",50))
ObservationNumber <- rep(seq(1,50),3)
ObservedValue <- runif(150)
mydat <- as.data.frame(cbind(Case, ObservationNumber, ObservedValue),stringsAsFactors = F)
mydat$ObservedValue <- as.numeric(mydat$ObservedValue)
result <- data.frame()
for(c in unique(mydat$Case)){
result <- rbind(result, data.frame(Case=c,Diff=
mydat$ObservedValue[mydat$Case==c & mydat$ObservationNumber == min(mydat$ObservationNumber)] -
mydat$ObservedValue[mydat$Case==c & mydat$ObservationNumber == max(mydat$ObservationNumber)]
))
}
...为了 100% 确定,我再次将其扩大到 4 个案例,每个案例有 500 个观察值(2000 行),它仍然在不到 1 秒的时间内完成:
Case <- c(rep("A",500), rep("B",500),rep("C",500), rep("D",500))
ObservationNumber <- rep(seq(1,500),4)
ObservedValue <- runif(2000)
mydat <- as.data.frame(cbind(Case, ObservationNumber, ObservedValue),stringsAsFactors = F)
mydat$ObservedValue <- as.numeric(mydat$ObservedValue)
result <- data.frame()
for(c in unique(mydat$Case)){
result <- rbind(result, data.frame(Case=c,Diff=
mydat$ObservedValue[mydat$Case==c & mydat$ObservationNumber == min(mydat$ObservationNumber)] -
mydat$ObservedValue[mydat$Case==c & mydat$ObservationNumber == max(mydat$ObservationNumber)]
))
}
我喜欢使用 dplyr
库来解决这些 grouping/summarising 问题:
library(dplyr)
df %>%
arrange(ObservationNumber) %>%
group_by(Case) %>%
summarise(diff = last(ObservedValue) - first(ObservedValue))