R - 将数据帧中不同字符串长度的列拆分为仅包含一个字符的多个列

lea*_*023 2 split r

我有一个这样的数据框:

Name     S1     S2     S3     Symbol
n_12     2.3    6.1    0      A
n_13     3.4    3.7    0      ACM
n_14     1.3    1.0    0      BN
n_23     2.0    4.1    0      NOPXY
Run Code Online (Sandbox Code Playgroud)

我希望将最后一列Symbol分成多个列,每个列都有一个字符或什么都没有.

    Name     S1     S2     S3     Sy1     Sy2     Sy3     Sy4     Sy5
    n_12     2.3    6.1    0      A                               
    n_13     3.4    3.7    0      A       C       M               
    n_14     1.3    1.0    0      B       N                       
    n_23     2.0    4.1    0      N       O       P       X       Y
Run Code Online (Sandbox Code Playgroud)

感谢您对此提供的任何帮助.

div*_*san 7

一种方法是tidyr::separate将包含字符串的单个列拆分为包含子字符串的多个列.

df
  Name  S1  S2 S3 Symbol
1 n_12 2.3 6.1  0      A
2 n_13 3.4 3.7  0    ACM
3 n_14 1.3 1.0  0     BN
4 n_23 2.0 4.1  0  NOPXY
Run Code Online (Sandbox Code Playgroud)

sep=用于参数separate可以接受一个正则表达式,或数字向量列出该串中的位置以分割上.因为我们想要在每个字符之后进行拆分,所以我们希望给出从1到最长字符串长度的数字序列(-1因为我们不需要在最后一个字符之后拆分).最长字符串的长度用计算max(nchar(.$Symbol)).感谢Rich Scriven指出它nchar是矢量化的,所以不需要调用sapply.

然后,我们创建一个字符向量,其中包含要拆分的列的名称Symbol.在您的情况下,我们可以粘贴'Sy'到相同的数字序列来获取c('Sy1', 'Sy2' ...)

df %>%
    tidyr::separate(Symbol,
                    sep = seq_len(max(nchar(.$Symbol)) - 1),
                    into = paste0('Sy', seq_len(max(nchar(.$Symbol)))))

  Name  S1  S2 S3 Sy1 Sy2 Sy3 Sy4 Sy5
1 n_12 2.3 6.1  0   A                
2 n_13 3.4 3.7  0   A   C   M        
3 n_14 1.3 1.0  0   B   N            
4 n_23 2.0 4.1  0   N   O   P   X   Y
Run Code Online (Sandbox Code Playgroud)

如果您收到以下错误:

Error in nchar(.$Symbol) : 'nchar()' requires a character vector
Run Code Online (Sandbox Code Playgroud)

那么它很可能df$Symbol是类型factor(创建或加载时的默认值data.frame)character.

您可以提供read.tabledata.frame使用参数stringsAsFactor=F来保持Symbol变量不被转换为factor或将其转换回character.

Tidyverse选项(可以在调用之前插入管道tidyr::separate:

df <- df %>%
    dplyr::mutate(Symbol = as.character(Symbol))
Run Code Online (Sandbox Code Playgroud)

或与基地R:

df$Symbol <- as.character(df$Symbol)
Run Code Online (Sandbox Code Playgroud)