【问题标题】:Calculate difference between two observations in a single case for a number of separate cases in R为 R 中的多个单独案例计算单个案例中两个观察值之间的差异
【发布时间】:2017-09-16 20:09:48
【问题描述】:

我有一个类似于以下的数据集。

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)为每个案例创建单独的数据集(例如通过过滤)来执行减法的方法,这是我能够想出的唯一方法拥有。

有没有人对如何做到这一点有任何其他想法?

**在示例中,行也是按顺序排列的,但在实际数据集中它们不是。结果,我不能只取每组的第一行和最后一行;我需要在每组中获取具有最大值和最小值的行。下面的两个答案都很好地解决了这个问题。

【问题讨论】:

标签: r subtraction


【解决方案1】:

我喜欢使用dplyr 库来解决这些类型的分组/总结问题:

library(dplyr)
df %>% 
    arrange(ObservationNumber) %>%
    group_by(Case) %>% 
    summarise(diff = last(ObservedValue) - first(ObservedValue))

【讨论】:

  • arrange 在这种情况下不是必需的。
  • @ycw 难道我不需要它以防数据不是由ObservationNumber排序的吗?
  • 然后我想在那里添加arrange 更安全。好!
  • 谢谢!我没有想到 dplyr 会是正确的软件包,但这可以完成工作并且非常简单!
【解决方案2】:
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)]
  ))
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-17
    • 2020-10-26
    • 2023-03-05
    相关资源
    最近更新 更多