如何在数据中找到类似的字符串

时间:2016-06-26 12:54:20

标签: r

我的数据看起来像这样

df<- structure(list(A = structure(c(7L, 6L, 5L, 4L, 3L, 2L, 1L, 1L, 
1L), .Label = c("", "P42356;Q8N8J0;A4QPH2", "P67809;Q9Y2T7", 
"Q08554", "Q13835", "Q5T749", "Q9NZT1"), class = "factor"), B = structure(c(9L, 
8L, 7L, 6L, 5L, 4L, 3L, 2L, 1L), .Label = c("P62861", "P62906", 
"P62979;P0CG47;P0CG48", "P63241;Q6IS14", "Q02413", "Q07955", 
"Q08554", "Q5T749", "Q9UQ80"), class = "factor"), C = structure(c(9L, 
8L, 7L, 6L, 5L, 4L, 3L, 2L, 1L), .Label = c("", "P62807;O60814;P57053;Q99879;Q99877;Q93079;Q5QNW6;P58876", 
"P63241;Q6IS14", "Q02413", "Q16658", "Q5T750", "Q6P1N9", "Q99497", 
"Q9UQ80"), class = "factor")), .Names = c("A", "B", "C"), class = "data.frame", row.names = c(NA, 
-9L))

我想计算每列中有多少元素,包括用a分隔的元素; ,例如在这种情况下

第一列有9个,第二列有12个元素,第三列有16个元素。然后我想检查元素在其他列中重复的次数。例如

string      number of times       columns
Q5T749           2              1,2

然后删除df中多次看到的字符串

2 个答案:

答案 0 :(得分:1)

对于每列中元素的计数,请使用此

sapply(df,function(x) length(unlist(sapply(strsplit(as.character(x),"\\s+"),strsplit,split=";"))))

为计算重复次数,请使用此

words <- lapply(df,function(x) unlist(sapply(strsplit(as.character(x),"\\s+"),strsplit,split=";")))
dup_table <- table(unlist(words))
dup_table

删除重复有一种非常糟糕的方法

pat <- names(dup_table)[unname(dup_table)>1]
for(i in pat)
 df <- as.data.frame.list(lapply(df,function(x) gsub(pattern = i,replacement = "",x)))

但是,只有一个问题。它将取代特定模式的所有出现。

答案 1 :(得分:1)

解决此问题的一种方法是首先将数据重新组织为更方便使用的表单。 tidyrdplyr包对这类事情非常有用。

library(tidyr)
df$index <- 1:nrow(df)
df <- gather(df, key = 'variable', value = 'value', -index, na.rm = TRUE)
df <- separate(df, "value", into = paste("x", 1:(1 + max(nchar(gsub("[^;]", "", df$value)))), sep = ""), sep = ";", fill = "right")
df <- gather(df, "which", "value", -index, -variable)

一旦你这样做,计算每个元素很容易:

addmargins(t(table(df[, c("variable", "value")])), margin = 2)

删除重复项也很容易。

df <- df[!duplicated(df$value), ]

如果你真的想把数据重新放回原件中(虽然我不推荐)。

df <- spread(df, key = "variable", value = "value")
library(dplyr)
summarize(group_by(df, index), 
          A = paste(na.omit(A), collapse = ";"), 
          B = paste(na.omit(B), collapse = ";"), 
          C = paste(na.omit(C), collapse = ";"))