R 如何在不同的列中找到相似字符串的百分比

R 如何在不同的列中找到相似字符串的百分比,r,R,我有一个数据如下 df<-structure(list(V1 = structure(c(5L, 1L, 7L, 3L, 2L, 4L, 6L, 6L ), .Label = c("CPSIAAAIAAVNALHGR", "DLNYCFSGMSDHR", "FPEHELIVDPQR", "IADPDAVKPDDWDEDAPSK", "LWADHGVQACFGR", "WGEAGAEYVVESTGVFTTMEK", "YYVTIIDAPGHR"), class = "factor"),

我有一个数据如下

df<-structure(list(V1 = structure(c(5L, 1L, 7L, 3L, 2L, 4L, 6L, 6L
), .Label = c("CPSIAAAIAAVNALHGR", "DLNYCFSGMSDHR", "FPEHELIVDPQR", 
"IADPDAVKPDDWDEDAPSK", "LWADHGVQACFGR", "WGEAGAEYVVESTGVFTTMEK", 
"YYVTIIDAPGHR"), class = "factor"), V2 = structure(c(5L, 2L, 
7L, 3L, 4L, 6L, 1L, 1L), .Label = c("", "CPSIAAAIAAVNALHGR", 
"GCITIIGGGDTATCCAK", "HVGPGVLSMANAGPNTNGSQFFICTIK", "LLELGPKPEVAQQTR", 
"MVCCSAWSEDHPICNLFTCGFDR", "YYVTIIDAPGHR"), class = "factor"), 
    V3 = structure(c(4L, 3L, 2L, 4L, 3L, 1L, 1L, 1L), .Label = c("", 
    "AVCMLSNTTAIAEAWAR", "DLNYCFSGMSDHR", "FPEHELIVDPQR"), class = "factor")), .Names = c("V1", 
"V2", "V3"), class = "data.frame", row.names = c(NA, -8L))
这意味着第一个字符串
cpsiaaavnalhgr
在第一列和第二列中重复<代码>YYVTIIDAPGHR在第一列和第二列中重复。等等

然后给我一个百分比,第一列有8行,在这8行中,它与第2列共享2行,所以它有2/8*100=25%的共享 第一股与第三股3/8*100=37% 第2列与第3列的份额为0%
etc etc

我真的觉得在删除每行的重复项(即考虑匹配的唯一字符串)后,公共Sting的数量更有用。所以,我正在更新我的解决方案,并添加了更多的代码以获得维恩图

library(dplyr)
library(tidyr)
library(gplots)

# reshape dataset
df_reshaped = df %>% 
  gather(column, string) %>% 
  filter(string != '') %>%
  distinct()

# dataset that shows all strings and in which columns they appear
df_result1 = df_reshaped %>% 
  group_by(string) %>% 
  summarise(columns = paste(unique(column), collapse=","))

df_result1


# # A tibble: 12 x 2
#                        string columns
#                         <chr>   <chr>
# 1           AVCMLSNTTAIAEAWAR      V3
# 2           CPSIAAAIAAVNALHGR   V1,V2
# 3               DLNYCFSGMSDHR   V1,V3
# 4                FPEHELIVDPQR   V1,V3
# 5           GCITIIGGGDTATCCAK      V2
# 6 HVGPGVLSMANAGPNTNGSQFFICTIK      V2
# 7         IADPDAVKPDDWDEDAPSK      V1
# 8             LLELGPKPEVAQQTR      V2
# 9               LWADHGVQACFGR      V1
# 10     MVCCSAWSEDHPICNLFTCGFDR     V2
# 11       WGEAGAEYVVESTGVFTTMEK     V1
# 12                YYVTIIDAPGHR  V1,V2


# function to get number of common rows
f1 = function(v1, v2) {
  x1 = (df_reshaped %>% filter(column == v1))$string
  x2 = (df_reshaped %>% filter(column == v2))$string
  length(x2[x2 %in% x1]) }
f1 = Vectorize(f1)


# function to get number of rows of each column
f2 = function(v) {df_reshaped %>% filter(column == v) %>% nrow}
f2 = Vectorize(f2)

# dataset that shows overlap of columns (number of common strings)
expand.grid(unique(df_reshaped$column), unique(df_reshaped$column)) %>%
  filter(Var1 != Var2) %>%
  mutate(NumShared = f1(Var1, Var2),
         NumRows = f2(Var1),
         Prc = NumShared/NumRows) %>%
  arrange(Var1, Var2)

#   Var1 Var2 NumShared NumRows       Prc
# 1   V1   V2         2       7 0.2857143
# 2   V1   V3         2       7 0.2857143
# 3   V2   V1         2       6 0.3333333
# 4   V2   V3         0       6 0.0000000
# 5   V3   V1         2       3 0.6666667
# 6   V3   V2         0       3 0.0000000


# reshape dataset and create a Venn diagram
df_reshaped %>%
  mutate(exist = TRUE) %>%
  spread(column, exist, fill=FALSE) %>%
  select(-string) %>%
  venn()
库(dplyr)
图书馆(tidyr)
图书馆(gplots)
#重塑数据集
df_整形=df%>%
聚集(列、字符串)%%>%
过滤器(字符串!='')%>%
不同的()
#显示所有字符串及其所在列的数据集
df_result1=df_整形%>%
分组依据(字符串)%>%
摘要(列=粘贴(唯一(列),折叠=“,”)
df_结果1
##tibble:12 x 2
#字符串列
#                            
#1 AVCMLSNTTAIAWAR V3
#2 CPSIAAAVNALHGR V1、V2
#3 DLNYCFSGMSDHR V1、V3
#4 FPEHELIVDPQR V1、V3
#5 GCITIGGGDTATCCAK V2
#6 HVGPGVLSMANAGPTNGSQFFICTIK V2
#7 IAPDAVKPDDWDEDAPSK V1
#8 LLELGPKPPEVAQQTR V2
#9 LWADHGVQACFGR V1
#10 MVCCSAWSEDHPICNLFTCGFDR V2
#11 WGEAGAEYVESTGVFTTMEK V1
#12 YYVTIIDAPGHR V1,V2
#函数获取公共行数
f1=功能(v1,v2){
x1=(df_重塑%>%过滤器(列==v1))$string
x2=(df_重塑%>%过滤器(列==v2))$string
长度(x2[x2%在%x1中])
f1=矢量化(f1)
#函数获取每列的行数
f2=函数(v){df_整形%>%filter(column==v)%%>%nrow}
f2=矢量化(f2)
#显示列重叠(公共字符串数)的数据集
expand.grid(唯一(df_整形$column),唯一(df_整形$column))%>%
过滤器(Var1!=Var2)%>%
突变(NumShared=f1(Var1,Var2),
NumRows=f2(Var1),
Prc=NumShared/NumRows)%>%
排列(Var1,Var2)
#Var1 Var2 NumShared NumRows Prc
#1 V1 V2 7 0.2857143
#2 V1 V3 2 7 0.2857143
#3 V2 V1 26 0.3333333
#4 V2 V3 0 6 0.0000000
#5 V3 V1 2 0.66667
#6 V3 V2 0 3 0.0000000
#重塑数据集并创建维恩图
df_整形%>%
变异(存在=真)%>%
排列(列,存在,填充=假)%>%
选择(-string)%%>%
文恩()
维恩图如下所示:


显然,此图中显示的数字之和应该等于您在表
df_result1
中获得的唯一字符串的数量。在我们的例子中是12。

根据您发布的数据集,第1列和第3列共享4行,而不是3行。他们共享FPEHILIVDPQR两次,DLNYCFSGMSDHR和DLNYCFSGMSDHR。同样,在您的第一个期望输出中,您有两次“dlnycfsgsgmdhr 1,3”,并且有重复项是不好的。我试图在下面的解决方案中解决这些问题。您的百分比不清楚。请按预期更新output@Sotos谢谢你的留言。假设我们在第一列中有8个字符串。其中2个与第二列共享,因此A列与B列共享的百分比为2/8*100。现在明白了吗?我认为理解在一列中多次出现的字符串会发生什么是很重要的。您是否计划使用匹配的行数或唯一字符串数?例如,第V3列中的DLNYCFSGMSDHR应算作与第1列的一个或两个匹配项?@AntoniosK replicate应算作两个匹配项(但请告诉我您是否也可以给我一个唯一的解决方案)如果我们只有3列,如果我们有许多列,而它们的名称不是V呢?您必须以类似的方式将
gather
命令中的
V1:V3
替换为列的名称。其余的应该与代码保持相同,代码将识别您有多少列、使用哪些名称以及检查共享行的列对数。例如,我可以执行此c(col1、col2、col3、col10、col50)?还有,能不能帮我画一个情节?我喜欢并接受您的回答是的,您可以在
聚集
命令中使用类似的内容。您可以执行
收集(列、字符串、col1、col2、col3、col10、col50)
。这样,如果您有任何其他列,它们将不会在这里被考虑。你想创造什么样的情节?我认为你不需要经历那么多麻烦。类似于
df%%>%gather(var,string)%%>%filter(string!='')%%>%groupby(string)%%>%summary(common=toString(unique(var))
就足够了
library(dplyr)
library(tidyr)
library(gplots)

# reshape dataset
df_reshaped = df %>% 
  gather(column, string) %>% 
  filter(string != '') %>%
  distinct()

# dataset that shows all strings and in which columns they appear
df_result1 = df_reshaped %>% 
  group_by(string) %>% 
  summarise(columns = paste(unique(column), collapse=","))

df_result1


# # A tibble: 12 x 2
#                        string columns
#                         <chr>   <chr>
# 1           AVCMLSNTTAIAEAWAR      V3
# 2           CPSIAAAIAAVNALHGR   V1,V2
# 3               DLNYCFSGMSDHR   V1,V3
# 4                FPEHELIVDPQR   V1,V3
# 5           GCITIIGGGDTATCCAK      V2
# 6 HVGPGVLSMANAGPNTNGSQFFICTIK      V2
# 7         IADPDAVKPDDWDEDAPSK      V1
# 8             LLELGPKPEVAQQTR      V2
# 9               LWADHGVQACFGR      V1
# 10     MVCCSAWSEDHPICNLFTCGFDR     V2
# 11       WGEAGAEYVVESTGVFTTMEK     V1
# 12                YYVTIIDAPGHR  V1,V2


# function to get number of common rows
f1 = function(v1, v2) {
  x1 = (df_reshaped %>% filter(column == v1))$string
  x2 = (df_reshaped %>% filter(column == v2))$string
  length(x2[x2 %in% x1]) }
f1 = Vectorize(f1)


# function to get number of rows of each column
f2 = function(v) {df_reshaped %>% filter(column == v) %>% nrow}
f2 = Vectorize(f2)

# dataset that shows overlap of columns (number of common strings)
expand.grid(unique(df_reshaped$column), unique(df_reshaped$column)) %>%
  filter(Var1 != Var2) %>%
  mutate(NumShared = f1(Var1, Var2),
         NumRows = f2(Var1),
         Prc = NumShared/NumRows) %>%
  arrange(Var1, Var2)

#   Var1 Var2 NumShared NumRows       Prc
# 1   V1   V2         2       7 0.2857143
# 2   V1   V3         2       7 0.2857143
# 3   V2   V1         2       6 0.3333333
# 4   V2   V3         0       6 0.0000000
# 5   V3   V1         2       3 0.6666667
# 6   V3   V2         0       3 0.0000000


# reshape dataset and create a Venn diagram
df_reshaped %>%
  mutate(exist = TRUE) %>%
  spread(column, exist, fill=FALSE) %>%
  select(-string) %>%
  venn()