我有一个项目数据集,我正在尝试根据主题和收到的资金进行分析。 我有一个“主题”列,其中列出了几个关键字。我在列表中列出了所有可能的唯一关键字,并且我正在尝试对每个关键字求和收到的总资金,并将其存储在数据框中。
举个例子,我的初始数据集是:
df
项目 | 主题 | 资金 |
---|---|---|
项目1 | 农业、水、食品 | 50 000 |
项目2 | 农业、数字化 | 100 000 |
项目3 | 农业、食品 | 50 000 |
项目4 | 城市规划、食品、水、数字 | 200 000 |
项目5 | 农业 | 30 000 |
我的关键字列表“keywords_list”是包含“农业”、“水”、“食品”、“数字”、“城市规划”的字符列表。
我想要的结果是:
主题分析
关键词 | 数 | 资金 |
---|---|---|
农业 | 4 | 230 000 |
水 | 2 | 250 000 |
食物 | 3 | 300 000 |
数字化 | 2 | 300 000 |
城市规划 | 1 | 200 000 |
由于这些功能,我已经成功获得了前两列
themes_string_sep <- strsplit(df$Themes, split = ",")
keywords_list <- unlist(themes_string_sep)
themes_analysis <- as.data.frame(table(keywords_list))
keywords_list <- unique(keywords_list)
但是,我无法通过搜索关键字找到如何汇总资金的方法。 我尝试了 ifelse 函数的不同变体: 1.
themes_analysis$Funding <- 0
themes_analysis$Funding <- ifelse((str_detect(df$Themes, themes_analysis$Keywords))== TRUE, sum(themes_analysis$sum_funding, df$Funding), themes_analysis$Funding)
返回“
str_detect()
中的错误:!无法回收string
(大小312)来匹配pattern
(大小93)。回溯:1.base::ifelse(...) 2.stringr:: str_detect(df $主题,themes_analysis $资金)“
2)
themes_analysis$Funding <- 0
themes_analysis$Funding <- ifelse((df$Themes %in% themes_analysis$Keywords))== TRUE, sum(themes_analysis$Funding, df$Funding), themes_analysis$Funding)
返回错误“
$<-.data.frame
(*tmp*
, Funding, value = c(318793741, 318793741, : 替换表有 312 行,替换表有 93 行”)
themes_analysis$Funding <- sum(df[which(df$Themes %in% themes_analysis$Keywords), 3])
这给了我每行相同的错误数字,这不是我想要的。到目前为止我在网上找不到任何答案。
有人知道如何解决这个问题吗?
使用
dplyr
和 tidyr
您可以使用
dd |>
tidyr::separate_longer_delim(Themes, ", ") |>
dplyr::summarize(count=n(), funding=sum(Funding), .by=Themes)
获取
Themes count funding
1 Agriculture 4 230000
2 Water 2 250000
3 Food 3 300000
4 Digital 2 300000
5 Urban planning 1 200000
不必担心自己搜索列,只需通过为每个值创建单独的行,将多值单元格拆分为整齐的格式。
测试
dd <- data.frame(Projects = c("Project 1", "Project 2", "Project 3", "Project 4", "Project 5"),
Themes = c("Agriculture, Water, Food", "Agriculture, Digital", "Agriculture, Food", "Urban planning, Food, Water, Digital", "Agriculture"),
Funding = c(50000L, 100000L, 50000L, 200000L, 30000L))