【问题标题】:R - Nested for loops with multiple conditions using grepl and identicalR - 使用 grepl 和相同的具有多个条件的嵌套 for 循环
【发布时间】:2016-10-21 16:18:55
【问题描述】:

如果仅由一个国家/地区提供,我将尝试将所有水果标记为“1”,否则标记为“0”。

我有两张数据表:

表 1:

水果 - 每行都有不同的水果,例如苹果、香蕉、桃子等……

国家/地区 - 每行都有 2 位 iso 格式的水果主要供应国家/地区,例如美国、英国、NO 等......

SourceUnique - 这是我要在包含仅由一个国家提供的水果的行中用“1”填充的列,否则为“0”。

表 2:

国家/地区 - 每行都有供应商的国家/地区,采用 2 位 iso 格式,如最后一个表格。

Supplies - 每行都有一个供应商提供的水果列表,例如:第 1 行是“苹果、香蕉”,第 2 行是“菠萝、桃子、梨子、苹果”等...

这两个表都是从 CSV 文件中导入的,那么我的代码如下:

Table1$SourceUnique=rep(1,length(Table1$Country))

for(i in 1:length(Table1$Country)){
  for(k in 1:length(Table2$Country)){
    if(grepl(Table1$Fruit[i], Table2$Supplies[k])==TRUE && identical(Table1$Country[i], Table2$Country[k])==FALSE){
      Table1$SourceUnique[i]=0
    }
  }
}

我没有收到任何错误,但 SourceUnique 列未正确填写。我得到 1 和 0,有些是正确的,有些不是。经过大量搜索和折腾后,我接受了我不知道并且需要帮助的事实,因此任何建议或解决方案都会很棒。

谢谢。

编辑以获取更多信息:

有些水果有很多来自同一个国家的供应商,Table2$Supplies 里面乱七八糟的词让人讨厌。

示例数据:

Table1$Country <- c("UK","US","NO")
Table1$Fruit <- c("Apple","Banana","Pear")

Table2$Country <- c("UK","US","UK")
Table2$Supplies <- c("Apple,Pear","Banana,Pear","Banana and Apple")

再次编辑:

当我用数字单独运行它们时,我的代码中的 grepl 和相同的工作。我不明白为什么它们在我的循环中不起作用......理论上我的代码循环通过“供应”,搜索两个条件并在两个条件都满足时返回 0。然后它移动到下一个 i(“水果”)并重复。也许 && 是我的问题?据我所知,这似乎是正确的。

Excel 解决方案也适用于我的目的,但我对 Excel 的经验不足,不知道从哪里开始。

【问题讨论】:

  • 嗨,欢迎来到 SO。请考虑阅读How to Ask 以及如何生成reproducible example。它使其他人更容易帮助您。
  • 抱歉,我尝试使用 HTML 创建一个小型数据表,但它似乎不起作用,所以我尝试尽可能地描述性。我的数据是投资者而不是水果,所以我不能分享 CSV 文件......两个有 3 个随机行的表可以工作。
  • 给定示例数据的预期输出是什么?
  • 表 1 中的新列有 3 行,分别为 1、0 和 0。Apple 为 1,因为它仅由英国提供。另外两个是 0,因为香蕉由英国和美国供应,梨主要由挪威供应,但我们可以看到它们也由美国和英国供应。
  • Supplies 的真实等效项中提取相关值是否可行?在您的示例数据中,这可以通过在出现正则表达式 "\\s*(and|,)\\s*" 时进行拆分来完成。

标签: r excel csv for-loop grepl


【解决方案1】:

也许您可以通过计算每个国家/地区的表 2 中每种水果的出现次数来简化问题:

for (i in Table1$Fruit){
  as.integer(rowSums(table(grepl(i,Table2$Supplies),Table2$Country))[2]==1)
}

这为您提供1 用于表 2 中每个国家/地区仅出现一次的水果,否则为0

【讨论】:

  • 感谢您的回答!这对一些人来说是可行的,但不幸的是,一些水果有很多来自同一个国家的供应商。
  • 我明白了。我正在相应地更新。这并没有太大的不同。
【解决方案2】:

假设可以构造一个正则表达式来从您的真实数据中的Supplies 列中提取“fruit”的值,这是解决该问题的一种数据操作方法。

# prepare your sample data
fruit <- suppliers <- list()

fruit$Fruit <- c("Apple","Banana","Pear")
fruit$Country <- c("UK","US","NO")
fruit <- data.frame(fruit)

suppliers$Country <- c("UK","US","UK")
suppliers$Supplies <- c("Apple,Pear","Banana,Pear","Banana and Apple")
suppliers <- data.frame(suppliers)

library(dplyr)
library(tidyr)  # version 0.5.0 or later

# data manipulation for the desired result
suppliers %>%
    # split values of Supplies into a new row at each occurance of sep
    separate_rows(Supplies, sep = "\\s*(and|,)\\s*") %>%
    group_by(Supplies) %>%
    # summarize which fruit are supplied from only one country
    summarize(SourceUnique = as.numeric(n_distinct(Country) == 1)) %>%
    left_join(fruit, ., by = c("Fruit" = "Supplies"))
#        Fruit Country SourceUnique
#     1  Apple      UK            1
#     2 Banana      US            0
#     3   Pear      NO            0

如果需要速度,可以使用data.tables 来制定相同的公式,它为处理大数据提供了出色的性能。

【讨论】:

  • 令人讨厌的是,仅从 Supplies 列中提取水果名称并不容易......在某些单元格中有很多 cmets。非常感谢你帮助我!
猜你喜欢
  • 1970-01-01
  • 2017-03-15
  • 2023-01-29
  • 1970-01-01
  • 2021-04-29
  • 1970-01-01
  • 2018-09-30
  • 1970-01-01
  • 2019-03-10
相关资源
最近更新 更多