将值的数据框转换为二进制数据框,其中每个唯一值都是一列
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
输出的名称作为行序列,将 list
到 data.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")
我正在从一个 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
输出的名称作为行序列,将 list
到 data.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")