在R中基于字符串中的字母分配数字值

4
我有一个数据框,只有一列,共有235,886行。每一行对应英语单词中的一个单词。
例如:
> words[10000:10005,1]

[1] 抗传染主义者 抗传染的 反常规的 反常规主义 抗痉挛的 [6] 抗体决定因子
我想做的是根据每行中的字母将其转换为数字。因此,如果“a”= 1,“b”= 2,“c”= 3,“d”= 4,则“abcd”= 10。有人知道如何做到这一点吗?
我的最终目标是拥有一个函数,可以扫描数据框以查找给定的数字值,并返回所有具有该值的字符串,即单词。因此,从上面的示例继续,如果我要求值为9,则此函数将返回“dad”和任何其他具有数值9的行。

喜欢 sum(match(strsplit(x, "")[[1]], letters)) 吗? - A5C1D2H2I1M1N2O1R2T1
这正是我正在寻找的。非常感谢你的帮助! - BenL126
2个回答

4
您可以使用strsplitmatch的组合。我加了一个tolower,以确保我们匹配正确的内容。
这是一个实现这些步骤的函数:
word_value <- function(words) {
  temp <- strsplit(tolower(words), "", TRUE)
  vapply(temp, function(x) sum(match(x, letters)), integer(1L))
}

这里是一个示例向量:
myvec <- c("and", "dad", "cat", "fox", "mom", "add", "dan")

测试一下:

word_value(myvec)
# [1] 19  9 24 45 41  9 19

myvec[word_value(myvec) == 9]
# [1] "dad" "add"

myvec[word_value(myvec) > 20]
# [1] "cat" "fox" "mom"

4
您可以使用utf8ToInt函数。
#using the sample data from Ananda's answer
offset <- utf8ToInt("a") - 1
d <- vapply(tolower(myvec), 
  function(ii) sum(utf8ToInt(ii) - offset), FUN.VALUE = double(1L))
#and dad cat fox mom add dan 
# 19   9  24  45  41   9  19

d[d > 20]
#cat fox mom 
# 24  45  41

使用偏移量是必要的,因为utf8ToInt("a")得到的是97,但是你想让"a"等于1。
如果需要,使用stack进行包装将为输出提供不同的格式:
d <- stack(vapply(tolower(myvec), 
  function(ii) sum(utf8ToInt(ii) - offset), FUN.VALUE = double(1L)))
#  values ind
#1     19 and
#2      9 dad
#3     24 cat
#4     45 fox
#5     41 mom
#6      9 add
#7     19 dan

d[d$values > 20,]
#  values ind
#3     24 cat
#4     45 fox
#5     41 mom

2
不错。两个建议:将 utf8ToInt("a") + 1 移到内部函数之外的 sapply 中,并将 sapply 更改为 vapply。+1 - A5C1D2H2I1M1N2O1R2T1
你正在为每个单词计算 utf8ToInt("a") + 1,这似乎是不必要的。你可以将其作为一个固定值添加到你的 vapply 中,或者只计算一次。请参见此处的示例。 - A5C1D2H2I1M1N2O1R2T1
1
我想知道如果我们处理可能包含标点符号的单词,比如“自尊心”,这个函数应该如何改变。 - A5C1D2H2I1M1N2O1R2T1
@AnandaMahto 很好的问题!我有两个快速想法,但我还没有测试或深入思考。一个是使用类似于chartr的东西将不需要的字符转换为"\\",这将是带有偏移量的0,另一个是使用子集(即类似于sum(utf8ToInt(ii)[utf8ToInt(ii) > 96] - offset)的东西)。我会考虑一下,但现在得去睡觉了。 - Jota
1
我正在考虑使用 gsub 去除不必要的内容。这将给我们带来与使用 match(..., nomatch = 0L) 相同的结果。 - A5C1D2H2I1M1N2O1R2T1
1
已添加到我的SOfun包,希望你不介意。如果你想让我在文档中做出任何更改,请告诉我。 - A5C1D2H2I1M1N2O1R2T1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接