如何计算由分号分隔的字符串

4

我的数据如下:

df <- structure(list(V1 = structure(c(7L, 4L, 8L, 8L, 5L, 3L, 1L, 1L, 
2L, 1L, 6L), .Label = c("", "cell and biogenesis;transport", 
"differentiation;metabolic process;regulation;stimulus", "MAPK cascade;cell and biogenesis", 
"MAPK cascade;cell and biogenesis;transport", "metabolic process;regulation;stimulus;transport", 
"mRNA;stimulus;transport", "targeting"), class = "factor")), .Names = "V1", class = "data.frame", row.names = c(NA, 
-11L))

我想要计算有多少相似的字符串,并记录它们来自哪一行。每个字符串用分号;分隔,但它们属于它们所在的行。
我希望输出结果如下:
String                           Count        position 
mRNA                                 1        1
stimulus                             3        1,6,11
transport                            4        1,5,9,11
MAPK cascade                         2        2,5
cell and biogenesis                  3        2,5,9
targeting                            2        3,4
regulation of mRNA stability         1        1
regulation                           2        6,11
differentiation                      1        6,11
metabolic process                    2        6,11

这个计数显示了整个数据中每个字符串(这些字符串由分号分隔)被重复的次数。 第二列显示它们所在的位置,例如mRNA只出现在第一行,因此为1。刺激物在第1行、第6行和第11行都有出现,因此为1、6和11。

一些行是空白的,但它们也被计算为行。

3个回答

4
在下面的代码中,我们做了以下事情:
  1. 添加行号作为一列。
  2. 使用strplit将每个字符串分割成其组件,并将结果存储在称为string的列中。
  3. strsplit返回一个列表。我们使用unnest将列表组件堆叠起来创建一个“长”数据框架,从而得到一个“整洁”的数据框架,准备好进行汇总。
  4. string分组并返回一个新的数据框架,计算每个字符串的出现频率并给出每个字符串实例最初出现的原始行号。

library(tidyverse)

df$V1 = as.character(df$V1)

df %>% 
  rownames_to_column() %>% 
  mutate(string = strsplit(V1, ";")) %>% 
  unnest %>%
  group_by(string) %>%
  summarise(count = n(),
            rows = paste(rowname, collapse=","))
               string count     rows
1 cell and biogenesis     3    2,5,9
2     differentiation     1        6
3        MAPK cascade     2      2,5
4   metabolic process     2     6,11
5                mRNA     1        1
6          regulation     2     6,11
7            stimulus     3   1,6,11
8           targeting     2      3,4
9           transport     4 1,5,9,11
如果您计划对行号进行进一步处理,您可能希望将它们保留为数字值,而不是作为粘贴值的字符串。 在这种情况下,您可以执行以下操作:
df.new = df %>% 
  rownames_to_column("rows") %>% 
  mutate(string = strsplit(V1, ";")) %>% 
  select(-V1) %>%
  unnest

这将为您提供一个数据框,包含每个 stringrows 组合的一行。


3

一种基于R语言的方法:

# convert 'V1' to a character vector (only necessary of it isn't already)
df$V1 <- as.character(df$V1)

# get the unique strings
strng <- unique(unlist(strsplit(df$V1,';')))

# create a list with the rows for each unique string
lst <- lapply(strng, function(x) grep(x, df$V1, fixed = TRUE))

# get the counts for each string
count <- lengths(lst)

# collpase the list string positions into a string with the rownumbers for each string
pos <- sapply(lst, toString)

# put everything together in one dataframe
d <- data.frame(strng, count, pos)

您可以简化此方法为:
d <- data.frame(strng = unique(unlist(strsplit(df$V1,';'))))
lst <- lapply(d$strng, function(x) grep(x, df$V1, fixed = TRUE))
transform(d, count = lengths(lst), pos = sapply(lst, toString))

结果如下:
> d
                strng count         pos
1                mRNA     1           1
2            stimulus     3    1, 6, 11
3           transport     4 1, 5, 9, 11
4        MAPK cascade     2        2, 5
5 cell and biogenesis     3     2, 5, 9
6           targeting     2        3, 4
7     differentiation     1           6
8   metabolic process     2       6, 11
9          regulation     2       6, 11

1
一种可能的完整性解决方案是使用 data.table
library(data.table)
setDT(df)[, .(.I, unlist(tstrsplit(V1, ";", fixed = TRUE)))
          ][!is.na(V2), .(count = .N, pos = toString(sort(I))), 
            by = .(String = V2)]
#                 String count         pos
# 1:                mRNA     1           1
# 2:        MAPK cascade     2        2, 5
# 3:           targeting     2        3, 4
# 4:     differentiation     1           6
# 5: cell and biogenesis     3     2, 5, 9
# 6:   metabolic process     2       6, 11
# 7:            stimulus     3    1, 6, 11
# 8:           transport     4 1, 5, 9, 11
# 9:          regulation     2       6, 11

这基本上是将V1列按;分割并转换为长格式,同时绑定行索引(.I)。然后只需对行计数(.N)进行简单的聚合,并将位置绑定到每个String中的单个字符串。

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