如何获得包含来自另一个向量的相应值的字符的矩阵的行和

时间:2016-10-21 10:16:09

标签: r matrix

您好我从我的数据中提取了这个专栏:

x <- data.frame(Category=factor(c("xxyyxyxyx", "xxyyyyxyx", "xxyyxyxyy",
           "yxyyxyxyx", "xxyyxyyyx")))
> x
  Category
1 xxyyxyxyx
2 xxyyyyxyx
3 xxyyxyxyy
4 yxyyxyxyx
5 xxyyxyyyx 

我必须计算每行中每三个字符所产生的相应行和,所以我生成了这个矩阵:

xx <- t(apply(x, 1, function(x){strsplit(gsub("([[:alnum:]]{3})", "\\1 ", x), " ")[[1]]}))

> xx

         [,1]  [,2]  [,3] 
     [1,] "xxy" "yxy" "xyx"
     [2,] "xxy" "yyy" "xyx"
     [3,] "xxy" "yxy" "xyy"
     [4,] "yxy" "yxy" "xyx"
     [5,] "xxy" "yxy" "yyx"

每个xx单元格对应于此向量中给出的值

matval=c("xxy"=3, "yxy"=2, "xyx"=7, "xyy"=5, "yyx"=12, "yyy"= 4)

我希望基于矩阵xx在矩阵x中添加一个包含每行总和的列,即

x

   Category    RowSum
 1 xxyyxyxyx     12
 2 xxyyyyxyx     14
 3 xxyyxyxyy     10
 4 yxyyxyxyx     11
 5 xxyyxyyyx     17

非常感谢提前!

2 个答案:

答案 0 :(得分:4)

我们可以使用键/值索引替换'xx'中的值并获取rowSums

x$RowSum <- rowSums(`dim<-`(matval[xx], dim(xx)))

也可以使用strsplit

创建'xx'
 do.call(rbind, strsplit(as.character(x$Category), "(?<=.{3})", perl = TRUE))

答案 1 :(得分:3)

1) matval[xx]会给出各个值,然后可以将这些值整形为矩阵并求和:

transform(x, RowSum = rowSums(array(matval[xx], dim(xx))))

,并提供:

   Category RowSum
1 xxyyxyxyx     12
2 xxyyyyxyx     14
3 xxyyxyxyy     10
4 yxyyxyxyx     11
5 xxyyxyyyx     17

2)首先直接从x计算结果而不先计算xx的替代方案如下。它提取每三个字符并将matval[...]应用于每个这样的提取,然后对得到的矩阵求和。

library(gsubfn)

transform(x, RowSums = 
   colSums(strapply(paste(Category), "...", s ~ matval[s], simplify = TRUE)))

注意:另一种计算xx的方法是在每隔三个字符后插入一个空格,将其读入数据框并将其转换为矩阵。

as.matrix(read.table(text = gsub("(...)", "\\1 ", x$Category)))

或使用read.fwf根据3个固定宽度字段(每个字符3个字符)读取它:

as.matrix(read.fwf(textConnection(paste(x$Category)), rep(3, 3)))

或使用substring

from <- seq(1, 9, 3)
to <- from + 3 - 1
t(sapply(x$Category, substring, from, to))