0

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

谢谢

4

3 回答 3

4

您可以尝试concat.split.expanded我的“splitstackshape”包中的功能:

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))
于 2013-10-06T17:06:06.697 回答
1

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

  1. 在分号上拆分数据`
  2. 创建列,用零/假填充空列

# 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]
于 2013-10-06T17:11:34.590 回答
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
于 2013-10-06T17:13:27.407 回答