在 R 中匹配和记录

matching and recording in R

我有一个这样的数据框,叫做 df:

a  b  c  d  e  f  
b  c  f  a  a  a  
d  f  a  b  c  c  
f  e  d  f  f  d  

第一行实际上是列名。举个例子来解释这里的意思:df[1,1]b,意思是从ab有关系,所以列中的值代表有关系从 'column name' 到该条目。
我想创建一个6*6维度的matrix(df1),列名和行名都是df的列名。如果存在从 'i' 到 'j' 的关系,则 (i,j) 条目为 1,否则为 0。

我想要的输出是:

    a  b  c  d  e  f
a   0  1  0  1  0  1
b   0  0  1  0  1  1
c   1  0  0  1  0  1
d   1  1  0  0  0  1
e   1  0  1  0  0  1
f   1  0  1  1  0  0

如何使用 R 中的循环执行此操作?
如何在没有循环的情况下做到这一点,并且只使用基本的 R?
如何在 R 中使用一些花哨的包来做到这一点?

你可以通过整形来做到这一点。

library(dplyr)
library(tidyr)

data %>%
  gather(from, to) %>%
  distinct %>%
  mutate(value = 1) %>%
  spread(to, value, fill = 0)

使用 reshape2 包,这是一种方法。我的示例数据将所有列都作为字符。您使用 melt() 以长格式重塑数据。然后,您使用同一个包中的 dcast()

library(magrittr)
library(reshape2)

melt(mydf, measure.vars = names(mydf)) %>%
dcast(variable ~ value, length)

  variable a b c d e f
1        a 0 1 0 1 0 1
2        b 0 0 1 0 1 1
3        c 1 0 0 1 0 1
4        d 1 1 0 0 0 1
5        e 1 0 1 0 0 1
6        f 1 0 1 1 0 0

编辑 正如 akrun 在下面提到的,您可以使用 reshape2 包中的 recast() 完成所有工作。

recast(mydf, measure.var= names(mydf),variable~value, length)

数据

mydf <- structure(list(a = c("b", "d", "f"), b = c("c", "f", "e"), c = c("f", 
"a", "d"), d = c("a", "b", "f"), e = c("a", "c", "f"), f = c("a", 
"c", "d")), .Names = c("a", "b", "c", "d", "e", "f"), class = "data.frame", row.names = c(NA, 
-3L))

另一个使用 dplyr 的解决方案非常简洁和智能。我建议使用该解决方案。

这是使用 R 中的大多数基本函数解决您的问题的替代方案。

假设您的数据框有 n 列和 m 行,即 n <- ncol(df)m <- nrow(df)

output_matrix <- matrix(rep(0, n*n), ncol = n)
for(i in 1:n){
    for(j in 1:m){
        # UTF to integer conversion
        # utf8ToInt("a") = 97
        rowWithRelation <- utf8ToInt(df[j, i]) - 96
        output_matrix[rowWithRelation, i] <- 1
    }
}
rownames(output_matrix) <- letters[seq(from = 1, to = n)]
colnames(output_matrix) <- letters[seq(from = 1, to = n)]

只需使用table:

table(colnames(mydf)[col(mydf)], unlist(mydf) )

#    a b c d e f
#  a 0 1 0 1 0 1
#  b 0 0 1 0 1 1
#  c 1 0 0 1 0 1
#  d 1 1 0 0 0 1
#  e 1 0 1 0 0 1
#  f 1 0 1 1 0 0

如果您有多个匹配项,则:

pmin(table(colnames(mydf)[col(mydf)], unlist(mydf) ), 1)