用数字替换数组中的字符

Replacing characters in an array with numbers

我从 excel 文件中读入了数据,并将其制成矢量。 然后我把它做成一个 3d 数组。

形成数组的向量,以及数组内部现在包含字符,如下所示:

D <- c('g', 't', NA, 'd')
nPeriods = 3
column.names = c('aaa', 'bbb')
row.names = c('jjj', 'hhh')
threeD.names = c(1:nPeriods)
E = array(c(D), dim=c(2, 2, nPeriods),
          dimnames = list(row.names, column.names, threeD.names))

但是,现在我想将 'g'、't' 等分配为具有起始值的变量,例如

g = 5
t = 2
d = 7

但我知道如何做到这一点的唯一方法是手动找出它是数组的哪个元素并像那样分配它,例如

E[1,1,]=5

当它是一个大矩阵时,每次我引用一个元素时都很难找到相应的位置。我知道向量的每个元素(不是 NA)都是唯一的,所以我想知道,是否有引用数组每个元素的快捷方式? (也许是 apply 家族的东西?但是他们太多了)。

稍后我还需要参考它们来遍历 nPeriods。昨天有人告诉我我可以这样做:

for (i in 2:nPeriods){
  C[1,1,i]=C[1,1,i-1]*2
}

但在现实生活中,我的矩阵可能非常大,所以我宁愿只能用 d、t 等来引用。

此任务在列表中更易于管理。您可以使用以下内容:

# Example data
D <- c('g', 't', NA, 'd')
nPeriods = 3
column.names = c('aaa', 'bbb')
row.names = c('jjj', 'hhh')
threeD.names = c(1:nPeriods)
E = array(c(D), dim=c(2, 2, nPeriods),
          dimnames = list(row.names, column.names, threeD.names))

# Convert array to list
array_list <- lapply(seq(dim(E)[3]), function(x) E[,,x])

# Re-assign values
array_converted <- lapply(array_list, function(x){
  x <- ifelse(x == "g", 5, x) # your conversion values
  x <- ifelse(x == "t", 2, x)
  x <- ifelse(x == "d", 7, x)
  x <- apply(x, 2, as.numeric) # Ensures values are numeric
  return(x)
})

# For final format as array (if you want)
final_array <- simplify2array(array_converted)

如果将替换值存储在命名向量中,则可以使用 apply 按名称替换元素。 apply 自动处理循环,如果所有 non-NA 元素都是数字,甚至将结果转换为数字数组。请注意,apply 调用中的 1:3 指的是数组的三个维度,而不是第三个维度的长度,因此无论数组有多大,这都应该有效。

values <- c(g = 5,
            t = 2,
            d = 7)

num_array <- apply(E, 1:3, function(x) values[x])

num_array

, , 1

    aaa bbb
jjj   5  NA
hhh   2   7

, , 2

    aaa bbb
jjj   5  NA
hhh   2   7

, , 3

    aaa bbb
jjj   5  NA
hhh   2   7

你的第二个问题不清楚,但你可以which有效地获取元素。您只需要遍历切片:

result <- num_array
for (i in 2:dim(num_array)[3]) {
  idx <- which(E[, , 1] == 'g', arr.ind = T)
  row <- idx[1, 'row']
  col <- idx[1, 'col']
  result[row, col, i] <- result[row, col, i-1] * 2
}

, , 1

    aaa bbb
jjj   5  NA
hhh   2   7

, , 2

    aaa bbb
jjj  10  NA
hhh   2   7

, , 3

    aaa bbb
jjj  20  NA
hhh   2   7

如果您想为每个字符存储操作(相对简单的操作),您可以利用 R 的一些 meta-programming 功能:

funcs <- c(g = '*', t = '+', d = '-')
modifiers <- c(g = 2, t = 3, d = 4)

num_array <- apply(E, 1:3, function(x) values[x])

result <- num_array
for (i in 2:dim(num_array)[3]) {
  for (j in names(values)) {
    idx <- which(E[, , 1] == j, arr.ind = T)
    row <- idx[1, 'row']
    col <- idx[1, 'col']
    result[row, col, i] <- do.call(funcs[j], args = list(result[row, col, i-1], modifiers[j]))
  }
}

, , 1

    aaa bbb
jjj   5  NA
hhh   2   7

, , 2

    aaa bbb
jjj  10  NA
hhh   5   3

, , 3

    aaa bbb
jjj  20  NA
hhh   8  -1