【问题标题】:In R, use if loop with agrep to assign value在 R 中,使用 if 循环和 agrep 来分配值
【发布时间】:2021-03-19 18:13:01
【问题描述】:

模式列表如下:

pattern <- c('aaa','bbb','ccc','ddd')

X 来自 df 看起来像:

df$X <- c('aaa-053','aaa-001','aab','bbb')

我尝试做的是:使用agrep根据df$X在pattern中找到匹配的名称,然后根据匹配结果为现有列'column2'赋值,例如,如果'aaa-053'匹配'aaa',则 'aaa' 将是 'column2' 中的值,如果不匹配,则返回该列中的 na。

for (i in 1:length(pattern)) {
 match <- agrep(pattern, df$X, ignore.case=TRUE, max=0)
 if agrep = TRUE {
   df$column2 <- pattern
 } else {df$column2 <- na
 }
}

df 中的理想 column2 如下所示:

'aaa','aaa',na,'bbb'

【问题讨论】:

  • aaa 与您的aab 匹配时,您认为会发生什么?

标签: r loops if-statement agrep


【解决方案1】:

agrep 本身并不能让您确定在倍数匹配时使用哪个。例如,

agrep(pattern[1], df$x)
# [1] 1 2 3

这对前两个有意义,但第三个不在您的预期值之内。同样,它可以为给定的字符串选择多个模式。

这里有一个替代方案:

D <- adist(pattern, df$x, fixed = FALSE)
D
#      [,1] [,2] [,3] [,4]
# [1,]    0    0    1    3
# [2,]    3    3    2    0
# [3,]    3    3    3    3
# [4,]    3    3    3    3
D[D > 0] <- NA
D
#      [,1] [,2] [,3] [,4]
# [1,]    0    0   NA   NA
# [2,]   NA   NA   NA    0
# [3,]   NA   NA   NA   NA
# [4,]   NA   NA   NA   NA
apply(D, 2, function(z) which.min(z)[1])
# [1]  1  1 NA  2
pattern[apply(D, 2, function(z) which.min(z)[1])]
# [1] "aaa" "aaa" NA    "bbb"

【讨论】:

  • 我认为这适用于数值数据,但我的情况是基于字符值,这就是我最初尝试使用 agrep 的原因
  • 不知道你的意思是什么。 agrep 适用于字符串,而不是数字,adist 也是如此。这个答案的重点是(1)证明你对单一匹配的假设是有缺陷的; (2) 提出一种方法来尝试减轻该缺点。这个答案的“数字”部分是找到字符串之间的最小“距离”,这应该表示最佳匹配。如果你想避免数字,那么我建议你要么使用永远不会像你的样本那样有重叠风险的数据,要么设计比模糊字符串匹配更直观的方法。祝你好运!
  • 另一个观点:给定您的示例数据,这给出了您期望的答案,作为字符串。是否存在使此代码功能不佳的数据的其他条件或属性?是否有其他数据不起作用?如果它在您的真实数据上失败,那么如果您不改进您的问题以包含更具代表性的样本数据,那么您将无法期待更好的结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-23
  • 2018-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多