【问题标题】:map one dataframe to another将一个数据框映射到另一个
【发布时间】:2020-08-29 16:23:39
【问题描述】:

我有一个包含个人食物数量的数据框:

set.seed(1)
quantity <- data.frame(apple = sample(0:10, 5, replace = TRUE),
                       egg = sample(0:10, 5, replace = TRUE),
                       beer = sample(0:10, 5, replace = TRUE))

例如。第一个人吃了8个苹果,6个鸡蛋,喝了0瓶啤酒,一共5个人

我还有一个市场重量和营养摄入量的参考表:

reference <- data.frame(name = c("apple", "apple", "egg", "beer", "beer", "beer"),
                        market_weight = c(0.4, 0.6, 1, 0.2, 0.7, 0.1),
                        nutr1 = sample(1:999, 6, replace = TRUE),
                        nutr2 = sample(1:999, 6, replace = TRUE),
                        nutr3 = sample(1:999, 6, replace = TRUE))

对于每个人,我需要根据他们吃的食物量知道营养摄入量(即 nutr1)。

预期结果(5 行 - 参与者每行):

nutr1    nutr2    nutr3
7814.8  4996.4    9053.6  
  W        T        K  
.....    ....     .....

我的(低效)解决方案:

我在这里加入数量和营养摄入量

library(dplyr)
merged <- quantity %>%
  t %>%
  as.data.frame %>%
  tibble::rownames_to_column() %>%
  `colnames<-`(c("name","id1","id2", "id3", "id4", "id5")) %>%
  right_join(., reference, by= "name") %>%
  na.omit

在这里,我将quantities * market_weight * nutrients(1 到 3)相乘并为每种营养素求和

out <- merged %>%
  mutate(mutr1_final = id1 * market_weight * nutr1,
         mutr2_final = id1 * market_weight * nutr2,
         mutr3_final = id1 * market_weight * nutr3) %>%
  summarise_at(., vars(c(mutr1_final, mutr2_final, mutr3_final)), funs(sum))

对于真实数据,数据框数量包含 40k 行(又名参与者),营养素的数量为 80 左右。 这样做的有效方法是什么?谢谢

【问题讨论】:

  • 如何考虑苹果或啤酒的类型?
  • @DanielO 只是澄清weight 的一种方式。红苹果重 0.4,青苹果重 0.6。在实践中,对代码没有用处
  • 第 1 个人有 8 个苹果,如果我不知道在计算中使用参考表中的哪种类型,我怎么可能知道他们摄入了多少营养?
  • 我刚刚编辑了问题并删除了不必要的 type 变量 - 希望它更清楚。重量代表market_weight,所以 8 个苹果按如下方式划分:8*0.4 有一些营养价值,8*0.6 有其他营养价值
  • 你能给出至少 1 人所需的实际数字输出吗?您的要求没有意义,您是否添加了 8*0.4*... + 8*0.6*...?你是不是假设他们吃了所有类型的苹果?

标签: r dataframe dictionary dplyr


【解决方案1】:

解决方案:

set.seed(1)
quantity <- data.frame(apple = sample(0:10, 5, replace = TRUE),
                       egg = sample(0:10, 5, replace = TRUE),
                       beer = sample(0:10, 5, replace = TRUE))

reference <- data.frame(name = c("apple", "apple", "egg", "beer", "beer", "beer"),
                        market_weight = c(0.4, 0.6, 1, 0.2, 0.7, 0.1),
                        nutr1 = sample(1:999, 6, replace = TRUE),
                        nutr2 = sample(1:999, 6, replace = TRUE),
                        nutr3 = sample(1:999, 6, replace = TRUE)) %>% 
 # multiply market_weight by nutrients 
  mutate(nutr1 = market_weight*nutr1,          
         nutr2 = market_weight*nutr2,
         nutr3 = market_weight*nutr3) %>%
 # sum within fruit name
  group_by(name) %>% 
  summarise_all(sum) %>%
  as.data.frame() %>%
  select(-market_weight)

# merge quantity and reference (same line: quantity and combined food intake)
merged <- t(quantity) %>%
  as.data.frame %>%
  tibble::rownames_to_column(., "name") %>%
  right_join(., reference, by="name")

# multiplication and summation
out <- matrix(data=NA, nrow=5, ncol=3) %>%
  as.data.frame %>%
  `colnames<-`(colnames(reference)[2:4])
for(i in 2:6) {
  for(j in 7:9){
    out[i-1,j-6] = sum(merged[, i] * merged[, j])
  }
}

我们感谢更有效的解决方案!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-01
    • 2018-02-13
    • 1970-01-01
    • 1970-01-01
    • 2018-10-09
    相关资源
    最近更新 更多