【问题标题】:R - loop through a list and calculate values to be stored in matrixR - 遍历列表并计算要存储在矩阵中的值
【发布时间】:2021-02-14 15:11:04
【问题描述】:

晚上好, 我有以下清单:

        lf <- 1 / 100 * c(
  A = 6.756, B = 1.234, C = 2.302, D = 3.518, E = 10.508, F = 1.843, G = 1.667,
  H = 5.041, I = 5.763, J = 0.127, K = 0.639, L = 3.330, M = 1.990, N = 5.583,
  O = 6.210, P = 1.596, Q = 0.079, R = 4.953, S = 5.234, T = 7.492, U = 2.282,
  V = 0.809, W = 1.952, X = 0.124, Y = 1.633, Z = 0.061, ` ` = 17.272)

还有一段文字:

text <- c("THIS IS A TEST")

我正在尝试编写一个循环,以便文本中的每个字母从 lf 接收右上方的数字。 我希望将其存储在矩阵中,以便在应用函数后可以找到最大值。

我开始了

  n <- length(lf)
mat <- matrix(ncol=2, nrow=n)

for (i in 1:n) {

  var1[[i]] <- 

}

但我似乎无法解决这个问题。 如何编写一个遍历列表 (lf) 值并将每个计算值存储在矩阵中的函数?

非常感谢您的帮助 =)

上面的数字代表对数可能性(这是一个密码问题)。我要找到一个字母(即“K”)在尝试破译一个用一个字母加密的代码时给出的所有可能性的最低总和。

我发现了如何获取给定文本(包括空格)的总和

sum(log(letterfrequencies[match(plaintext, names(letterfrequencies))]))

现在我必须在尝试加密文本上的每个字母时找到最低的对数可能性,我认为我需要一个循环来尝试每个字母

(因为我没有正确解释问题,所以我删除了我之前的问题)

【问题讨论】:

  • 你需要字母表中所有字母的总和

标签: r loops iteration


【解决方案1】:

您可以在没有循环的情况下执行此操作:

sapply(strsplit(text, ""), function(x) lf[x])
#>      [,1]
#> T 0.07492
#> H 0.05041
#> I 0.05763
#> S 0.05234
#>   0.17272
#> I 0.05763
#> S 0.05234
#>   0.17272
#> A 0.06756
#>   0.17272
#> T 0.07492
#> E 0.10508
#> S 0.05234
#> T 0.07492

如果你只想对单个字母的值求和,一个小的包装函数应该可以解决问题:

sum_letters <- function(letter, text) {
  sum(strsplit(text, "")[[1]] %in% letter) * lf[letter]
}

这允许你做:

sum_letters("T", text)
#>       T 
#> 0.22476

或者获取字母表中所有字母的总和:

sums <- sapply(LETTERS, sum_letters, text = text, USE.NAMES = FALSE)

sums
#>       A       B       C       D       E       F       G       H       I       J 
#> 0.06756 0.00000 0.00000 0.00000 0.10508 0.00000 0.00000 0.05041 0.11526 0.00000 
#>       K       L       M       N       O       P       Q       R       S       T 
#> 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.15702 0.22476 
#>       U       V       W       X       Y       Z 
#> 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000

从而找到最合适的:

which.max(sums)
#>  T 
#> 20

reprex package 创建于 2020-11-01 (v0.3.0)

【讨论】:

  • 嗯,我不需要每个字母的单独数字。我需要向量 lf 中一个字母的文本总和。
  • @rofl4breakfast 拆分后更容易做到这一点。即在与 Allan Cameron 的代码拆分后,堆栈并与 aggregate aggregate(values ~ ., stack(lf[strsplit(text, "")[[1]]]), FUN = sum) 得到总和
  • 可以改进答案,而不是直接使用sapply unlist 拆分成子集即lf[unlist(strsplit(text,""))]
【解决方案2】:

我们可以直接使用matrix

as.matrix( lf[regmatches(text, gregexpr('[A-Z ]', text))[[1]]])

-输出

#    [,1]
#T 0.07492
#H 0.05041
#I 0.05763
#S 0.05234
#  0.17272
#I 0.05763
#S 0.05234
#  0.17272
#A 0.06756
#  0.17272
#T 0.07492
#E 0.10508
#S 0.05234
#T 0.07492

如果我们需要sum的群组

v1 <- lf[regmatches(text, gregexpr('[A-Z ]', text))[[1]]]
tapply(v1, names(v1), FUN = sum)
#          A       E       H       I       S       T 
#0.51816 0.06756 0.10508 0.05041 0.11526 0.15702 0.22476 

如果我们需要包含所有LETTERS

sapply(split(v1, factor(names(v1), levels = LETTERS)), sum)
#      A       B       C       D       E       F       G       H       I       J       K       L       M       N       O       P 
#0.06756 0.00000 0.00000 0.00000 0.10508 0.00000 0.00000 0.05041 0.11526 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 
#      Q       R       S       T       U       V       W       X       Y       Z 
#0.00000 0.00000 0.15702 0.22476 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-12
    • 2014-08-30
    • 2018-12-08
    • 2018-02-16
    • 2021-04-13
    相关资源
    最近更新 更多