我已将此文件读入R中的data.frame,如您所见,第5列包含一些以“;”分隔的值。是否可以将此data.frame转换为更大的data.frame并将第5列扩展为二进制向量?
> head(uinfo)
V1 V2 V3 V4 V5
1 100044 1899 1 5 831;55;198;8;450;7;39;5;111
2 100054 1987 2 6 0
3 100065 1989 1 57 0
4 100080 1986 1 31 113;41;44;48;91;96;42;79;92;35
5 100086 1986 1 129 0
6 100097 1981 1 75 0
所以,作为一个更简单的例子,如果我的前两行是:
1 100044 1899 1 5 1;2;4;7
2 100054 1987 2 6 3;8
我想得到:
1 100044 1899 1 5 1 1 0 1 0 0 1 0 0 0
2 100054 1987 2 6 0 0 1 0 0 0 0 1 0 0
我是否必须使用其他程序(如python)来预处理数据,或者是否可以通过某些应用函数来实现?
由于
答案 0 :(得分:4)
您可以尝试我的“splitstackshape”软件包中的concat.split.expanded
函数:
library(splitstackshape)
mydf
# V1 V2 V3 V4 V5
# 1 100044 1899 1 5 1;2;4;7
# 2 100054 1987 2 6 3;8
concat.split.expanded(mydf, "V5", sep=";", fill = 0)
# V1 V2 V3 V4 V5 V5_1 V5_2 V5_3 V5_4 V5_5 V5_6 V5_7 V5_8
# 1 100044 1899 1 5 1;2;4;7 1 1 0 1 0 0 1 0
# 2 100054 1987 2 6 3;8 0 0 1 0 0 0 0 1
添加drop = TRUE
以删除原始列。
这里,“mydf”定义为:
mydf <- structure(list(V1 = c(100044L, 100054L), V2 = c(1899L, 1987L),
V3 = 1:2, V4 = 5:6, V5 = c("1;2;4;7", "3;8")), .Names = c("V1",
"V2", "V3", "V4", "V5"), class = "data.frame", row.names = c(NA, -2L))
答案 1 :(得分:1)
这里的想法是有两个要求:
- 拆分分号`
上的数据- 创建列,用零/ FALSE填充空cols
醇>
#1很简单:使用strsplit
#2可以通过按新列数排序,并检查它们是否在新的splatted字符串中来完成。
library(data.table)
largest <- 1e3 # (Whatever your largest expected value)
newColNames <- as.character(seq(largest))
dat[, (newColNames) := as.data.table(t(sapply(strsplit(V5, ";"), "%in%", x=seq(largest))))]
# if you really want numeric (as opposed to logical)
dat[, (newColNames) := lapply(.SD, as.numeric), .SDcols=newColNames]
答案 2 :(得分:1)
使用基本功能(我认为步骤太多)
> df <- read.table(text=" 100044 1899 1 5 1;2;4;7
+ 100054 1987 2 6 3;8", header=F, stringsAsFactors=F) # data.frame
> pos <- sapply(strsplit(as.character(df[,5]), ";"), as.numeric)
> x <-rep(0, max(unlist(pos)))
> cbind(df, t(sapply(pos, function(y) replace(x, y, 1))))
V1 V2 V3 V4 V5 1 2 3 4 5 6 7 8
1 100044 1899 1 5 1;2;4;7 1 1 0 1 0 0 1 0
2 100054 1987 2 6 3;8 0 0 1 0 0 0 0 1