将一个数据框映射到另一个

时间:2020-05-13 12:56:57

标签: r dataframe dictionary dplyr

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

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))

对于真实数据,数据框数量包含4万行(又名参与者),养分数量为80-ish。 这是一种有效的方法吗?谢谢

1 个答案:

答案 0 :(得分:0)

解决方案:

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])
  }
}

感谢更有效的解决方案!