【问题标题】:Splitting one column into multiple columns将一列拆分为多列
【发布时间】:2013-01-23 12:28:51
【问题描述】:

我有一个巨大的数据集,其中有一列包括每个主题(行)的多个值。这是一个简化的示例数据框:

data <- data.frame(subject = c(1:8), sex = c(1, 2, 2, 1, 2, 1, 1, 2), 
              age = c(35, 29, 31, 46, 64, 57, 49, 58), 
              v1 = c("2", "0", "3,5", "2 1", "A,4", "B,1,C", "A and B,3", "5, 6 A or C"))

> data
  subject sex age          v1
1       1   1  35           2
2       2   2  29           0
3       3   2  31         3,5  # separated by a comma
4       4   1  46         2 1  # separated by a blank space
5       5   2  64         A,4
6       6   1  57       B,1,C
7       7   1  49   A and B,3
8       8   2  58 5, 6 A or C

我首先要删除第四列(v1)中的字母(ABA and B、...),然后将第四列拆分为多列,如下所示:

  subject sex age x1 x2 x3 x4 x5 x6
1       1   1  35  0  1  0  0  0  0        
2       2   2  29  0  0  0  0  0  0
3       3   2  31  0  0  1  0  1  0  
4       4   1  46  1  1  0  0  0  0
5       5   2  64  0  0  0  1  0  0
6       6   1  57  1  0  0  0  0  0
7       7   1  49  0  0  1  0  0  0
8       8   2  58  0  0  0  0  1  1

第一个受试者在 x2 处取 1,因为它在原始数据集中的 v1 处取 2,第三个受试者在 x3 和 x5 处取 1,因为它在原始数据集中的 v1 处取 3 和 5,依此类推。

我将不胜感激有关此问题的任何帮助。非常感谢。

【问题讨论】:

    标签: r


    【解决方案1】:

    您可以将此结果 cbind 到 data[-4] 并获得所需的内容:

     0+t(sapply(as.character(data$v1), function(line) 
            sapply(1:6, function(x) x %in% unlist(strsplit(line, split="\\s|\\,"))) ))
    #----------------
                [,1] [,2] [,3] [,4] [,5] [,6]
    2              0    1    0    0    0    0
    0              0    0    0    0    0    0
    3,5            0    0    1    0    1    0
    2 1            1    1    0    0    0    0
    A,4            0    0    0    1    0    0
    B,1,C          1    0    0    0    0    0
    A and B,3      0    0    1    0    0    0
    5, 6 A or C    0    0    0    0    1    1
    

    【讨论】:

      【解决方案2】:

      一个解决方案:

      r <- sapply(strsplit(as.character(dt$v1), "[^0-9]+"), as.numeric)
      m <- as.data.frame(t(sapply(r, function(x) {
              y <- rep(0, 6)
              y[x[!is.na(x)]] <- 1
              y
           })))
      data <- cbind(data[, c("subject", "sex", "age")], m)
      
      #   subject sex age V1 V2 V3 V4 V5 V6
      # 1       1   1  35  0  1  0  0  0  0
      # 2       2   2  29  0  0  0  0  0  0
      # 3       3   2  31  0  0  1  0  1  0
      # 4       4   1  46  1  1  0  0  0  0
      # 5       5   2  64  0  0  0  1  0  0
      # 6       6   1  57  1  0  0  0  0  0
      # 7       7   1  49  0  0  1  0  0  0
      # 8       8   2  58  0  0  0  0  1  1
      

      按照 DWin 的出色解决方案,m 可以修改为:

      m <- as.data.frame(t(sapply(r, function(x) {
              0 + 1:6 %in% x[!is.na(x)]
           })))
      

      【讨论】:

      • 感谢您的更新。我还有一个问题。这里我只给出一个简单的数据集,其中 v1 取最大值“6”。在我的真实数据中,由于它很大,是否有一种简单的方法可以自动确定 v1 的最大值而不是我自己指定它?谢谢。
      猜你喜欢
      • 2014-12-16
      • 2019-05-10
      • 2017-10-03
      • 2020-09-28
      • 2016-11-17
      相关资源
      最近更新 更多