【问题标题】:Calculating sum of certain values across two columns in R计算R中两列的某些值的总和
【发布时间】:2020-11-28 08:53:24
【问题描述】:

我目前有一个类似下面一堆成对相关性的数据框:

数据

structure(list(ID1 = c("A", "A", "A", "B", "B", "C"), ID2 = c("B", 
"C", "D", "C", "D", "D"), cor = c(0.6, 0.6, 0.2, 0.1, 0.9, 0.2
), value1 = c(50L, 50L, 50L, 20L, 20L, 30L), value2 = c(20L, 
30L, 100L, 30L, 100L, 100L)), class = "data.frame", row.names = c(NA, 
-6L))
  ID1 ID2 cor value1 value2
1   A   B 0.6     50     20
2   A   C 0.6     50     30
3   A   D 0.2     50    100
4   B   C 0.1     20     30
5   B   D 0.9     20    100
6   C   D 0.2     30    100

我正在尝试获取 cor 与 value1 或 value2 之间产品的所有 ID(即 B)的总和,具体取决于它来自 ID1 还是 ID2。

例如,B 的总和将是(cor x 值)

(0.6 x 50) + (0.1 x 30) + (0.9 x 100)

我基本上需要为大约 20000 个唯一 ID 执行此操作。我希望这是有道理的。我在 R 方面还不是很好(还)!

【问题讨论】:

  • BID2 中时,为什么corvalue1 相乘?这不直观。

标签: r


【解决方案1】:

除非您正在寻找dplyr 的回答方式,否则这是一种快速但有点不雅的方式:

cond1 <- df$ID1[df$ID1 == "B"]
sum1 <- sum(df$cor[cond1] * df$value1[cond1])

cond2 <- df$ID2[df$ID2 == "B"]
sum2 <- sum(df$cor[cond2] * df$value2[cond2])

finalsum = sum1 + sum2

基本上你想先看看B在ID1的哪一行,然后做积和,再看看B在ID2的哪一行,做同样的事情。

更新: 如果你有数千个 ID 怎么办?同样,我喜欢它快,所以用它创建一个函数:

prodsum <- function (df, ID) {
  cond1 <- df$ID1[df$ID1 == ID]
  sum1 <- sum(df$cor[cond1] * df$value1[cond1])

  cond2 <- df$ID2[df$ID2 == ID]
  sum2 <- sum(df$cor[cond2] * df$value2[cond2])

  return(sum1 + sum2)
}

然后prodsum(df, "B") 会给你原始问题的答案。您可以使用sapply() 来完成循环遍历数千个 ID 的工作:

IDs <- unique(c(df$ID1, df$ID2)) 
sapply(IDs, function (x) prodsum(df, x)

如果 ID 仅存在于 ID1 或 ID2 中,则可能存在问题,也可能不存在问题。我相信你可以写一个条件来处理这个问题。

【讨论】:

  • 问题是我有几千个ID。
【解决方案2】:

另一种看待事物的方式如下。

假设您的数据框名称是a

a1 <- subset(a,select=c(ID1,cor,value1))
a2 <- subset(a,select=c(ID2,cor,value1))

colnames(a2)[colnames(a2) == "ID2"] <- "ID1"

a3 <- rbind(a1,a2)

a3$MULTIPLY1 <- a3$cor * a3$value1

a4 <- a3 %>% group_by(ID1) %>% summarise(FINALVALUE = sum(MULTIPLY1))


# A tibble: 4 x 2
  ID1   FINALVALUE
  <chr>      <dbl>
1 A             70
2 B             50
3 C             38
4 D             34

希望这会在一定程度上有所帮助...!

【讨论】:

    【解决方案3】:

    这能满足你的需要吗?

    library(tidyverse)
    
    df2 <- df %>%
      pivot_longer(names_to = "names", values_to = "values", -c(cor:value2)) %>%
      mutate(value = if_else(names == "ID1", value2, value1),
             sum = cor * value) %>%
      group_by(values) %>%
      summarise(sum = sum(sum))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-18
      • 1970-01-01
      • 2022-07-15
      • 1970-01-01
      相关资源
      最近更新 更多