R 按列计算字符串部分的数目

R 按列计算字符串部分的数目,r,R,我有这样一个文本文件: V1 V2 V3 X N aaaaaabbbabab C T ababaaabaaabb V H babbbabaabbba col1 col2 col3 ....... col13 a 2 2 2 1 b 1 1 1 2 我想做的是计算每个V3的列中有多少a和多少b 因此,输出将如下所示: V1 V2 V3 X N aaaaaabbbab

我有这样一个文本文件:

V1 V2   V3
X  N    aaaaaabbbabab
C  T    ababaaabaaabb
V  H    babbbabaabbba
   col1  col2 col3 .......  col13
a  2     2    2             1
b  1     1    1             2
我想做的是计算每个V3的列中有多少a和多少b

因此,输出将如下所示:

V1 V2   V3
X  N    aaaaaabbbabab
C  T    ababaaabaaabb
V  H    babbbabaabbba
   col1  col2 col3 .......  col13
a  2     2    2             1
b  1     1    1             2
如何做到这一点

我尝试了count函数和子字符串,但没有成功


谢谢

这里有一个新版本来回答实际问题。仍然使用
gregexpr
,但这次使用的是索引。我必须花点心思来解释零计数单元(我不能在表中得到它?)


fooEDIT:解决方案在Gavin Simpson的评论后更正。现在可以了


为了避免多次转换为因子,可以对索引和tapply使用以下技巧:

tt <- c("aaaaaabbbabab","ababaaabaaabb","babbbabaabbba")

ttstr <- strsplit(tt,"")
ttf <- factor(unlist(ttstr))
n <- length(ttstr[[1]])
k <- length(ttstr)

> do.call(cbind,tapply(ttf,rep(1:n,k),table))
  1 2 3 4 5 6 7 8 9 10 11 12 13
a 2 2 2 1 2 3 1 1 2  2  1  1  1
b 1 1 1 2 1 0 2 2 1  1  2  2  2

假设
dat
包含您的数据,我们使用
strsplit()
来处理

tt <- matrix(unlist(strsplit(dat$V3, split = "")), ncol = 13, byrow = TRUE)
我们可以通过以下方式获得所需的结果,注意正确设置水平:

apply(tt, 2, function(x) c(table(factor(x, levels = c("a","b")))))
其中:

> apply(tt, 2, function(x) c(table(factor(x, levels = c("a","b")))))
  [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
a    2    2    2    1    2    3    1    1    2     2     1     1     1
b    1    1    1    2    1    0    2    2    1     1     2     2     2
要自动选择适当的级别,我们可以执行以下操作:

> lev <- levels(factor(tt))
> apply(tt, 2, function(x, levels) c(table(factor(x, levels = lev))), 
+       levels = lev)
  [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
a    2    2    2    1    2    3    1    1    2     2     1     1     1
b    1    1    1    2    1    0    2    2    1     1     2     2     2
>lev应用(tt,2,函数(x,级别)c(表(系数(x,级别=级别)),
+级别=lev)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
a 2 2 1 2 3 1 2 1 1 1 1
b 1 1 2 1 0 2 1 2 2 2 2

其中,在第一行中,我们将
tt
视为一个向量,并在将
tt
临时转换为一个因子后提取水平。然后我们将这些级别(
lev
)提供给
apply()
步骤,而不是明确说明级别。

这不是OP想要的。。。他在看逐列比较。我想你弄错了,我想按V3的子字符串的列来计算a和b,而不是按row@JorisMeys:这两种方法都有效,但都给出了警告:警告消息:在函数(…,deparse.level=1)中:结果行数不是向量长度(arg 1)的倍数@smack:那么您提供的数据与您拥有的数据不一样,因为当我用df$V3替换tt时,我没有收到警告。哪一行给了你警告?@Joris Meys:好的,我给了你一个数据的代表性示例,但感谢它工作了,但当我将其转换为数据帧时,数字消失了,并被a和b替换,但我想将这些数字绘制在图形中(x轴:列号(1..13)和y轴(a和b的编号)),我怎样才能在不丢失数字的情况下转换它,很抱歉问了很多问题,但我是新来的R@Joris事实上,两者都错了。我提出了与矩阵1相同的解决方案,然后意识到对于只包含“a”的“列”6,您得到了错误的答案。看看你的结果,它计算了3“b”和3“a”,这不可能是正确的-R正在默默地扩大a的计数。您需要根据我的回答在
表()
调用中设置正确的级别。@smack:您的代码出了问题,请不要忽略它。如果你收到警告,它就不起作用了。特别是如果你把它转换成数据帧,你会得到数字。@Gavin Simpson:你能解释一下你做了什么吗。@smack它和@Joris得到
tt
是一样的。区别在于我如何使用
table()
。让
table()
“a”
“b”
进行计数非常重要,即使其中一个缺失。方法是将
级别显式设置为
c(“a”、“b”)
。这足够了吗?或者我应该试着解释更多吗?不,我认为这足够了,但如果我想在列表中添加第三个变量,也许“c”我可以直接添加到正确的级别??我可以用什么来绘制这些数据帧呢???@smack实际上,我们可以简化最后一步,因为如果我们在
表中得到正确的计数,
apply()
将返回一个矩阵。@smack是的,只需将
“c”
添加到级别列表中即可。如果有很多,我们也可以自动执行这一步骤,以选择正确的级别。
> lev <- levels(factor(tt))
> apply(tt, 2, function(x, levels) c(table(factor(x, levels = lev))), 
+       levels = lev)
  [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
a    2    2    2    1    2    3    1    1    2     2     1     1     1
b    1    1    1    2    1    0    2    2    1     1     2     2     2