【问题标题】:Conditionally extracting multiple substrings and returning a value for each substring using a for-loop有条件地提取多个子字符串并使用 for 循环为每个子字符串返回一个值
【发布时间】:2018-05-14 06:23:37
【问题描述】:

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

  1. 对“区域”中的每个唯一元素使用 for 循环
  2. 从 df1 中的每一行的“country_name”中提取多个子字符串
  3. 将每个区域/行的多个子字符串存储为下一步的向量或列表
  4. 使用 df2 为 df1 中的每个区域/行向量返回子字符串所属的唯一元素的值。
  5. 生成的输出将类似于 df3

我有两个数据框:

第一个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 值,代码应该可以工作。

感谢所有查看此问题并提供解决方法的人:)

【问题讨论】:

    标签: r


    【解决方案1】:

    我们可以在将“country_name”拆分为“and”并按“zone”分组后生成left_join,得到“cost”的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,而是根据'country_name'中的模式执行left_join然后filter,得到'cost'的sum和'df1'的right_join

    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)
    

    【讨论】:

    • 我更喜欢第二种建议的方法,它允许在我需要过滤较长字符串的情况下使用 grepl。但两者都建议同样有效!
    猜你喜欢
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 2014-05-21
    • 2020-04-13
    • 1970-01-01
    • 1970-01-01
    • 2021-01-09
    • 2012-10-15
    相关资源
    最近更新 更多