通过将列与缺少数据的列表(strsplit)组合在一起而不使用索引来创建数据帧

时间:2016-07-23 23:59:10

标签: r na strsplit

道歉,如果这是显而易见的,我已经找到了什么东西,当有索引或缺少列时。但是,我认为不会为此工作。

示例数据:

df.test=data.frame( A=c("n,n,y,n"  ,"t", "j,k,k")
                   ,B=c("n,y,y,n"  ,"" , "k,k,k")
                   ,C=c("n,y,y,n,n","t", "j,k,j")
                   ,D=c(""         ,"" , "k,k,j")
                     )

df.test=lapply(df.test, function(x) as.character(x))
str(df.test)   # looks similar to my data

List of 4
 $ A: chr [1:3] "n,n,y,n" "t" "j,k,k"
 $ B: chr [1:3] "n,y,y,n" "" "k,k,k"
 $ C: chr [1:3] "n,y,y,n,n" "t" "j,k,j"
 $ D: chr [1:3] "" "" "k,k,j"

我的目标是数据框:

A B C D
n n n NA
n y y NA
y y y NA
n n n NA
t NA t NA
j k j k
k k k k
k k j j

我希望将A列作为参考,但它并不具有唯一值。但是,它具有每个列表允许的最大值数(我希望这是有意义的)。因此,应该删除C列表1中的第五个值,即n y y n n -> n y y n。 此外,需要添加缺失值(根据列A丢失)。 C中的额外值是来自其他软件的错误(我没有影响)。除了那些额外的值,它们彼此对应,例如,t应该在同一行(如果存在)。

到目前为止我做的最好的事情是制作一个矢量列表,列表有不同的长度,所以我不能将它们放在一起而且它们不相符。

df3=lapply(df.test, function(x) unlist(strsplit(x,',')))
str(df3)

List of 4
 $ A: chr [1:8] "n" "n" "y" "n" ...
 $ B: chr [1:7] "n" "y" "y" "n" ...
 $ C: chr [1:9] "n" "y" "y" "n" ...
 $ D: chr [1:3] "k" "k" "j"

2 个答案:

答案 0 :(得分:1)

由于您希望管理A列,我们可以先预先计算A列中字符串元素的字段长度。可以通过strsplit()上的初始df.test[[1L]]调用来完成,然后执行lengths()

然后,我们可以使用lapply()迭代所有列并使用strsplit()拆分它们。为了确保我们根据来自A列的控制长度限制每个拆分字符串向量,我们必须将每个拆分字符串向量从1索引到A列的长度,索引向量通过seq_len()计算。这可以使用Map()来完成,以并行地迭代拆分字符串向量和预先计算的长度向量。对分割字符串向量进行索引可以方便地完成两件事:(1)限制长度,以及(2)返回未在当前列的分割字符串向量中表示的尾部索引的NA。我们最终可以unlist()生成的分割字符串向量列表以获得单个列向量,并将整个事物包装在as.data.frame()中以将列表强制转换为data.frame。

ls1 <- lengths(strsplit(df.test[[1L]],','));
as.data.frame(lapply(df.test,function(x)
    unlist(Map(function(ss,l) ss[seq_len(l)],strsplit(x,','),ls1))
),stringsAsFactors=F);
##   A    B C    D
## 1 n    n n <NA>
## 2 n    y y <NA>
## 3 y    y y <NA>
## 4 n    n n <NA>
## 5 t <NA> t <NA>
## 6 j    k j    k
## 7 k    k k    k
## 8 k    k j    j

答案 1 :(得分:0)

请参阅上面bgoldst的答案。

以下是我提出的内容,以防任何人使用它。它适用于示例数据,但不是实际数据,只是在查看更好的答案时发布的原因。

再次感谢。

df6=lapply(df.test, function(x) strsplit(x,','))

  df7=data.frame()
  df7=lapply(df7, function(x) as.character(x))

  for (i in 1:length(df6$A)){
    for (ii in 1:length(df6$A[[i]])){
      df7=rbind(df7,sapply(df6,function(x) x[[i]][ii]))
    }
  }

  str(df7)

  print(df7)