R将data.frame的一列更改为二进制向量

时间:2013-10-06 16:58:56

标签: r binary dataframe

我已将此文件读入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)来预处理数据,或者是否可以通过某些应用函数来实现?

由于

3 个答案:

答案 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)

这里的想法是有两个要求:

  
      
  1. 拆分分号`
  2. 上的数据   
  3. 创建列,用零/ FALSE填充空cols
  4.   

#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