有条件地提取多个子字符串并使用for循环返回每个子字符串的值

时间:2018-05-14 06:23:37

标签: r

我想找到一个优雅的方法:

  1. 在'zone'
  2. 中使用for循环每个唯一元素
  3. 从df1
  4. 中的每一行的'country_name'中提取多个子字符串
  5. 将每个区域/行的多个子字符串存储为下一步的向量或列表
  6. 使用df2为df1中的每个区域/行向量返回子字符串所属的唯一元素的值。
  7. 产生的结果将类似于df3
  8. 我有两个数据帧:

    第一个data.frame:

    zone = c("A", "B", "C")
    country_name = c("Canada and UK", "UK and USA", "USA and Canada and UK") 
    df1 = data.frame(zone, country_name)
    

    第二个data.frame:

    zone_area = c("A", "A", "A", "B", "B", "B", "C", "C", "C")
    country_name = c("Canada", "UK", "USA", "Canada", "UK", "USA", "Canada", "UK", "USA")
    cost = c(4, 8, 6, 5, 6, 9, 8, 7, 5)
    df2 = data.frame(zone_area, country_name, cost)
    

    最终生成的data.frame 应该像df3:

    zone = c("A", "B", "C")
    country_name = c("Canada and UK", "UK and USA", "USA and Canada and UK")
    cost = c(12, 15, 20)
    df3 = data.frame(zone, country_name, cost)
    

    我需要使用for循环的原因是因为如果使用不同的zone值,代码应该可以工作。

    感谢所有观看此问题的人,并提供了一种方法:)

1 个答案:

答案 0 :(得分:1)

分割' country_name'后,我们可以left_join按'和'按'区'分组,得到sum'费用'并使用原始数据集执行right_join以获得预期输出

library(tidyverse)
df1 %>% 
   separate_rows(country_name, sep="\\s+and\\s+") %>%
   left_join(df2) %>% 
   group_by(zone) %>% 
   summarise(cost = sum(cost)) %>% 
   right_join(df1) %>%
   select(zone, country_name, cost)
# A tibble: 3 x 3
#  zone  country_name           cost
#   <fct> <fct>                 <dbl>
#1 A     Canada and UK            12
#2 B     UK and USA               15
#3 C     USA and Canada and UK    20

或者,不是使用separate_rows,而是根据&#39; country_name&#39;中的模式执行left_join然后filter,获取sum的{​​{1}} &#39;成本&#39;和right_join与&#39; df1&#39;

left_join(df2, df1, by = "zone") %>%
    group_by(zone) %>% 
    filter(grepl(gsub("\\s*and\\s*", "|", country_name.y[1]), country_name.x)) %>%
    summarise(cost = sum(cost)) %>%
    right_join(df1)