将值的数据框转换为二进制数据框,其中每个唯一值都是一列

Convert data frame of values into binary data frame where each unique value is a column

我正在从一个 csv 文件中读取数据,其中每一行都包含一些单独的字符串:

例如

data.csv ->
    x,f,t,h,b,g
    d,g,h
    g,h,a,s,d
    f
    q,w,e,r,t,y,u,i,o

data <- read.csv("data.csv", header = FALSE)

我想将此输入转换为一个数据框,其中列是输入中存在的一组唯一字符串。在这种情况下,列将是字符串集 {x,f,t,h,b,g,d,a,s,q,w,e,r,y,u,i,o}。此外,新数据框应该为输入数据框中的每一行包含一行,这样一列将具有值 1 如果列的名称出现在输入数据框中的该行中,或者 0 如果该输入行中不存在该列的名称。

在此示例中,所需的输出如下:

    x f t h b g d a s q w e r y u i o
   ----------------------------------
1 | 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0
2 | 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0
3 | 0 0 0 1 0 1 1 1 1 0 0 0 0 0 0 0 0
4 | 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
5 | 0 0 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1

下面的代码是我目前拥有的。但是,输出 df 最终成为一个数据框,其中的列似乎是正确的,但行数为 0。

我在 R 方面非常缺乏经验,这是我尝试将一些有用的东西组合在一起的尝试。在调用 apply() 之前,它似乎按预期工作,但意外地没有向 df.

添加任何内容
data <- read.csv("data.csv", header = FALSE)

columnNames = c()
for (row in data) {
  for (eventName in row) {
    if (!(eventName %in% columnNames)) {
      columnNames = c(columnNames, eventName)
    }
  }
}
columnNames = t(columnNames)

df = data.frame(columnNames)
colnames(df) = columnNames
df = df[-1,]

apply(data, 1, function(row, df) {
  dat = data.frame(columnNames)
  colnames(dat) = columnNames
  dat = dat[-1,]

  for (eventName in row) {
    if (eventName != "") {
      dat[1,eventName] = 1
    }
  }

  df = rbind(df, dat)
}, df)

脚本完成后,它告诉我有很多以下两种形式的警告:

9: In `[<-.factor`(`*tmp*`, iseq, value = 1) : invalid factor level, NA generated
10: In `[<-.factor`(`*tmp*`, iseq, value = 1) :
  invalid factor level, NA generated

我们可以在 split 通过 ,

调整列后使用 mtabulate
library(qdapTools)
mtabulate(strsplit(as.character(df1[,1]), ","))

或使用 base R 方法 split 将列 , 设置为 list 输出的名称作为行序列,将 listdata.frame (stack),将 'values' 列更改为 factor 并指定 levels,然后使用 table 获取频率。

table(transform(stack(setNames(strsplit(as.character(df1[,1]), ","), 1:nrow(df1)))[2:1], 
           values = factor(values, levels = unique(values))))
# 
#    x f t h b g d a s q w e r y u i o
#  1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0
#  2 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0
#  3 0 0 0 1 0 1 1 1 1 0 0 0 0 0 0 0 0
#  4 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
#  5 0 0 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1

更新

如果这不是单列,

mtabulate(apply(df2, 1, FUN = function(x) x[x!=""]))

as.data.frame.matrix(table(transform(stack(setNames(apply(df2, 1, 
     FUN = function(x) x[x!=""]), 
           1:nrow(df2)))[2:1],  values = factor(values, levels = unique(values)))))
#    
#    x f t h b g d a s q w e r y u i o
#  1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0
#  2 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0
#  3 0 0 0 1 0 1 1 1 1 0 0 0 0 0 0 0 0
#  4 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
#  5 0 0 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1

数据

df1 <- structure(list(V1 = c("x,f,t,h,b,g", "d,g,h", "g,h,a,s,d", "f", 
"q,w,e,r,t,y,u,i,o")), .Names = "V1", class = "data.frame", 
row.names = c(NA, -5L))

df2 <- structure(list(v1 = c("x", "d", "g", "f", "q"), v2 = c("f", "g", 
"h", "", "w"), v3 = c("t", "h", "a", "", "e"), v4 = c("h", "", 
"s", "", "r"), v5 = c("b", "", "d", "", "t"), v6 = c("g", "", 
"", "", "y"), v7 = c("", "", "", "", "u"), v8 = c("", "", "", 
"", "i"), v9 = c("", "", "", "", "o")), .Names = c("v1", "v2", 
"v3", "v4", "v5", "v6", "v7", "v8", "v9"), row.names = c(NA, 
-5L), class = "data.frame")