我有这样的数据
df<- structure(list(df1 = structure(1:7, .Label = c("A0A023J5X5",
"A0A023J5X7", "A0A023J5Y1", "A0A023J5Y8", "A0A023J5Z0", "A0A023J601",
"A0A023J609"), class = "factor"), df2 = structure(1:7, .Label = c("A0A023J5X5",
"A0A023J5X7", "A0A023J5Y1", "A0A023J5Y8", "A0A023J5Z0", "A0A023J601",
"A0A023J609"), class = "factor"), df3 = structure(c(2L, 3L, 4L,
1L, 1L, 1L, 1L), .Label = c("", "A0A023J5X5", "A0A023J5X7", "A0A023J5Y1"
), class = "factor"), df4 = structure(c(4L, 3L, 5L, 1L, 2L, 6L,
7L), .Label = c("A0A023J5Y8", "D3Z2H7", "O35945", "Q6ZPS9", "Q7TMW3",
"Q925B0-1", "Q9EPC1"), class = "factor"), df5 = structure(c(5L,
4L, 6L, 2L, 3L, 1L, 1L), .Label = c("", "A0A023J601", "A0A023J609",
"O35945", "Q6ZPS9", "Q7TMW3"), class = "factor")), .Names = c("df1",
"df2", "df3", "df4", "df5"), class = "data.frame", row.names = c(NA,
-7L))
我想找到每列中相同字符串的数量
所以像这样的输出就是我要找的东西
df1 df2 df3 df4 df5
df1 7 7 3 1 2
df2 7 7 3 1 2
df3 3 3 3 0 0
df4 1 1 0 7 3
df5 2 2 0 3 5
例如,第1列,有7个字符串,与df2列相同,因此它将得到7
答案 0 :(得分:2)
这里有一些用于循环的东西,因此大数据可能会很慢。它必须应对&#34;&#34;在原始数据中。
dimension = ncol(df)
result = matrix(data=0, nrow = dimension, ncol = dimension)
for (row in 1:dimension) {
for (col in 1:dimension) {
intersection = intersect(df[,row], df[,col])
# work round the "" in the data
intersection = intersection[!intersection == ""]
result[row,col] = length(intersection)
}
}
result.df = data.frame(result)
names(result.df) = names(df)
row.names(result.df) = names(df)
result.df
# df1 df2 df3 df4 df5
#df1 7 7 3 1 2
#df2 7 7 3 1 2
#df3 3 3 3 0 0
#df4 1 1 0 7 3
#df5 2 2 0 3 5
答案 1 :(得分:2)
另一种没有循环的解决方案,并使用外部产品比较将矩阵的每个元素与所有其他元素进行比较
1)您似乎将空字符串视为NA
df[df == ""] <- NA
2)使用outer
函数将矩阵的每个元素与所有其他元素进行比较。由于lapply
tmp <- lapply(df, function(x) outer(x, t(df), FUN = "=="))
3)求和以获得每个向量的匹配数
tmp <- lapply(tmp, function(x) apply(x, 2, sum, na.rm = T))
4)将每个向量粘贴到矩阵
中do.call(rbind, tmp)
## df1 df2 df3 df4 df5
## df1 7 7 3 1 2
## df2 7 7 3 1 2
## df3 3 3 3 0 0
## df4 1 1 0 7 3
## df5 2 2 0 3 5
答案 2 :(得分:0)
始终从概念化问题开始。这里有两个不同的步骤:
让自己回到高中时期的组合和排列。我们希望开发列对的所有组合,其中顺序无关紧要。幸运的是,有一个函数combn
可以做到这一点。让我们干净并使用df
。
> combn(dim(df)[2], 2)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 1 1 1 2 2 2 3 3 4
[2,] 2 3 4 5 3 4 5 4 5 5
> combn(names(df), 2)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] "df1" "df1" "df1" "df1" "df2" "df2" "df2" "df3" "df3" "df4"
[2,] "df2" "df3" "df4" "df5" "df3" "df4" "df5" "df4" "df5" "df5"
使用转置函数t
生成数据框。我为你的例子保留了这个亮点,除了使用确切的列名称这一点很简单。
df1 <- data.frame(t(combn(5,2)))
names(df1) <- c("first", "second")
根据您的示例,我发现简单的%in%
运算符足以满足您的解决方案。看看这个例子:
> sum(df$df1 %in% df$df5)
[1] 2
我使用sapply
函数生成所有匹配的简单向量。我取df1
数据框并使用第一列和第二列作为原始数据框df
的列索引,然后进行逐列比较。
df1$match <- sapply(1:dim(df1)[1], function(x) {
sum(df[,df1[x,1]] %in% df[,df1[x,2]])
})
查看输出以确认它是正确的:
> df1
first second match
1 1 2 7
2 1 3 3
3 1 4 1
4 1 5 2
5 2 3 3
6 2 4 1
7 2 5 2
8 3 4 0
9 3 5 4
10 4 5 3
这听起来很花哨,但事实上,一旦你将问题分解为两个步骤,它就会很简单。在将来尝试这样做,您将走向良好的编程实践。
答案 3 :(得分:0)
加载数据并将列(df1:df5)转换为唯一列,然后将其转换为一个因子以获取数值而不是字符串:
library(dplyr)
mydf_chr <- mydf %>%
mutate_all(.funs=as.character()) %>%
mutate_all(.funs=funs(gsub(pattern="^$",replacement="NA",x=.))) %>%
gather(Your_string) %>%
mutate(value=as.factor(value))
然后,您可以使用唯一因子的数字级别重新创建数据框,以识别df1:df5列中的哪个元素相同(不相似...)
Strings <- mydf_chr$value
Numeric_strings <- as.numeric(Strings)
YourDf <- as.data.frame(matrix(Numeric_strings,nrow=7,ncol=5))
names(YourDf) <- c(paste0("df",1:5))
您将获得以下结果:
df1 df2 df3 df4 df5
1 1 1 1 11 11
2 2 2 2 10 10
3 3 3 3 12 12
4 4 4 9 4 6
5 5 5 9 8 7
6 6 6 9 13 9
7 7 7 9 14 9
这意味着,对于istance,第4行有3个相同的字符串,如数据框中所示:
df1 df2 df3 df4 df5
4 A0A023J5Y8 A0A023J5Y8 A0A023J5Y8 A0A023J601