【问题标题】:Subtracting columns in two dataframes based on another column根据另一列减去两个数据框中的列
【发布时间】:2018-05-08 18:33:02
【问题描述】:

我的第一个数据集(MSdata1)如下所示

m.z       Intensity   Relative  Delta..ppm. RDB.equiv.  Composition 
301.14093   7646        100.00      -0.34     5.5       C16 H22 O4 Na
149.02331   4083458.5   23.60       -0.08     6.5       C8 H5 O3
279.15908   33256       18.64       -0.03     5.5       C16 H23 O4

我的第二个数据集(MSdata2)看起来像这样

m.z       Intensity    Relative Delta..ppm.  RDB.equiv. Composition 
331.11233   4324         94.00      -0.33    6.5        C17 H26 O5 Na
149.02331   4083458.5    23.60      -0.08    6.5        C8 H5 O3
279.15908   42315        18.64      -0.03    5.5        C16 H23 O4

我正在尝试根据每行的“ID”(即 $Composition 列)减去 $Intensity 列中的两个数据集。 (MSdata2$Intensity 减去 MSdata1$Intensity)

我的尝试是

!(data33$Composition %in% data3$Composition)

但是这个及其变体要么给我 TRUE/FALSE 输出,要么不幸地减去所有内容,这不是我的最终目标。我发现了类似的问题,但它们要么不处理字符串——要么它们的两个数据集的大小和内容非常相似。我的两个数据集将有很多不同的信息,并且自始至终具有相似之处 - 我想减去这些相似之处以更好地了解它们的差异。

这是,

m.z       Intensity    Relative Delta..ppm.  RDB.equiv. Composition 
301.14093   -7646       100.00      -0.34    5.5        C16 H22 O4 Na
149.02331   0            23.60      -0.08    6.5        C8 H5 O3
279.15908   9059         18.64      -0.03    5.5        C16 H23 O4

感谢您提供的任何帮助! :(

编辑 - 我已更改我的输出,以便在第一个数据集中找不到 $Composition 字符串,导致输出为负(例如,0-100 = -100)

【问题讨论】:

  • 您是否考虑过将两者与?merge 合并?
  • MSdata1和MSdata2有什么区别?

标签: r string dplyr chemistry


【解决方案1】:

我建议将dplyr::left_joinby="Composition" 一起使用。根据OP 表达的预期输出,他似乎有兴趣从MSdata2 中减去MSdata1

library(dplyr)

MSdata2 %>% left_join(select(MSdata1, Intensity, Composition), by="Composition") %>%
mutate(Intensity = ifelse(is.na(Intensity.y), Intensity.x, Intensity.x - Intensity.y)) %>%
select(-Intensity.y, -Intensity.x )

#        m.z Relative Delta..ppm. RDB.equiv.   Composition Intensity
# 1 331.1123    94.00       -0.33        6.5 C17 H26 O5 Na      4324
# 2 149.0233    23.60       -0.08        6.5      C8 H5 O3         0
# 3 279.1591    18.64       -0.03        5.5    C16 H23 O4      9059

已编辑:已添加答案以包含来自MSdata1 的行,而MSdata2 中没有匹配的行。这些行应该得到Intensity = -Intensity。一旦可以使用anti_join 找到这样的行,然后使用bind_rows 合并所有行。

MSdata2 %>% left_join(select(MSdata1, Intensity, Composition), by="Composition") %>%
mutate(Intensity = ifelse(is.na(Intensity.y), Intensity.x, Intensity.x - Intensity.y)) %>%
select(-Intensity.y, -Intensity.x ) %>%
bind_rows(anti_join(MSdata1, MSdata2, by="Composition") %>% mutate(Intensity = -Intensity))

#        m.z Relative Delta..ppm. RDB.equiv.   Composition Intensity
# 1 331.1123    94.00       -0.33        6.5 C17 H26 O5 Na      4324
# 2 149.0233    23.60       -0.08        6.5      C8 H5 O3         0
# 3 279.1591    18.64       -0.03        5.5    C16 H23 O4      9059
# 4 301.1409   100.00       -0.34        5.5 C16 H22 O4 Na     -7646

Edit#2:如果需要来自MSdata1 的所有记录,那么一次可以尝试:

MSdata1 %>% left_join(select(MSdata2, Intensity, Composition), by="Composition") %>%
mutate(Intensity = ifelse(is.na(Intensity.y), -Intensity.x, Intensity.y - Intensity.x)) %>%
  select(-Intensity.y, -Intensity.x )

#        m.z Relative Delta..ppm. RDB.equiv.   Composition Intensity
# 1 301.1409   100.00       -0.34        5.5 C16 H22 O4 Na     -7646
# 2 149.0233    23.60       -0.08        6.5      C8 H5 O3         0
# 3 279.1591    18.64       -0.03        5.5    C16 H23 O4      9059

数据:

MSdata1 <- read.table(text = 
"m.z       Intensity   Relative  Delta..ppm. RDB.equiv.  Composition 
301.14093   7646        100.00      -0.34     5.5       'C16 H22 O4 Na'
149.02331   4083458.5   23.60       -0.08     6.5       'C8 H5 O3'
279.15908   33256       18.64       -0.03     5.5       'C16 H23 O4'",
header = TRUE, stringsAsFactors = FALSE)

MSdata2 <- read.table(text = 
"m.z       Intensity    Relative Delta..ppm.  RDB.equiv. Composition 
331.11233   4324         94.00      -0.33    6.5        'C17 H26 O5 Na'
149.02331   4083458.5    23.60      -0.08    6.5        'C8 H5 O3'
279.15908   42315        18.64      -0.03    5.5        'C16 H23 O4'",
header = TRUE, stringsAsFactors = FALSE)

【讨论】:

  • @Ragstock 我认为您已经接受了这个答案,然后可能意外地删除了接受。但如果它不符合您的期望,请告诉我。我认为如果问题得到明确接受的答案,对未来的用户会更好。
  • 问题 - 所以我的计划是突出 MSdata1 中的差异,因此我在 MSdata2$Composition 中看到的 MSdata1$Composition 中不存在的任何内容 - 应该显示为负数(例如零 - 100 = -(负)100)。使用此代码,这是否已经完成?如果没有,我不确定我会怎么做。
  • @Ragstock 这在您的预期输出中没有提到,因此我目前的解决方案没有考虑它。这很容易做到。请使用预期输出更新您的问题。我会在一段时间内更新我的答案
  • 你是完全正确的,我没有意识到我在我的一个行中错过了一个否定的例子。它已被修复。谢谢
  • 请注意,我的例子(0-100 = -100)只是一个例子。我只需要不匹配的行来给出负强度(而不是保持不变)
【解决方案2】:
MSdata1 = MSdata1 = data.frame(m.z = c(301.14093, 149.02331, 279.15908), Intensity = c(7647, 4083458.5, 33256), Composition = c("C16 H22 O4 Na", "C8 H5 O3", "C16 H23 O4"))
MSdata2 = data.frame(m.z = c(331.11233, 149.02331, 279.15908), Intensity = c(4324, 4083458, 42315), Composition = c("C17 H26 O5 Na", "C8 H5 O3", "C16 H23 O4"))

MSdata2 %>% merge(MSdata1, by="m.z", all.x = TRUE) %>% select(-Composition.y) %>% replace(., is.na(.), 0) %>% mutate(Intensity = Intensity.x - Intensity.y) 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-28
    • 2021-12-07
    • 1970-01-01
    • 2018-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多