我有一个像这样的数据框:
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
我想将符号的最后一列分为多列,每列不包含一个字符或不包含任何字符。
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
谢谢您对此的任何帮助。
答案 0 :(得分:6)
一种方法是使用def game_print(newlines_before, text, newlines_after)
print ("\n" * newlines_before + text + "\n" * newlines_after)
,它将包含字符串的单个列拆分为包含子字符串的多个列。
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
的{{1}}参数接受正则表达式或列出要分割的字符串位置的数字矢量。由于我们想在每个字符后进行分割,因此我们希望给出一个从1到最长字符串(sep=
的长度的数字序列,因为我们不需要在最后一个字符后进行分割)。最长字符串的长度用separate
计算。感谢Rich Scriven指出-1
是矢量化的,因此不需要使用max(nchar(.$Symbol))
进行调用。
然后,我们使用要分隔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
的类型可能是Error in nchar(.$Symbol) : 'nchar()' requires a character vector
(创建或加载df$Symbol
时的默认值)而不是factor
。
您可以为data.frame
或character
提供参数read.table
,以防止将data.frame
变量转换为stringsAsFactor=F
或将其转换回Symbol
。
Tidyverse选项(可以在调用factor
之前插入到管道中:
character
或以R为底的
tidyr::separate
答案 1 :(得分:3)
以下是使用strcapture
的基本R版本:
ns <- max(nchar(dat$Symbol))
cbind(
dat,
strcapture(
paste(rep("(.)", ns), collapse=""),
format(dat$Symbol, width=ns),
proto=setNames(rep(list(""), ns), paste0("Sy",1:ns))
)
)
使用substring
的后期基本R加法,它遍历每个输入,包括每个子字符串的开始和结束:
dat[paste0("Sy",seq(ns))] <- matrix(substring(rep(dat$Symbol,each=ns),
seq(ns), seq(ns)), ncol=ns, byrow=TRUE)
# Name S1 S2 S3 Symbol Sy1 Sy2 Sy3 Sy4 Sy5
#1 n_12 2.3 6.1 0 A A
#2 n_13 3.4 3.7 0 ACM A C M
#3 n_14 1.3 1.0 0 BN B N
#4 n_23 2.0 4.1 0 NOPXY N O P X Y
答案 2 :(得分:1)
这是使用蛮力的R基:
string <- strsplit(df$Symbol, "")
ind <- max(lengths(string))
out <- data.frame(df, do.call(rbind, lapply(string, function(x) {
if(length(x) != ind){
c(x[1:length(x)], x[(length(x)+1):ind] )
}else{
x
}
})))
names(out) <- sub("X(\\d)", "Sy\\1", names(out))
print(out, na.print = "")
Name S1 S2 S3 Symbol Sy1 Sy2 Sy3 Sy4 Sy5
1 n_12 2.3 6.1 0 A A
2 n_13 3.4 3.7 0 ACM A C M
3 n_14 1.3 1.0 0 BN B N
4 n_23 2.0 4.1 0 NOPXY N O P X Y
答案 3 :(得分:0)
出于完整性考虑,这里是单行data.table
解决方案,使用tstrsplit()
。将要添加的列数是动态的,并且基于Symbol
的最大长度。
library(data.table)
dt <- fread("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")
dt[, paste0( "Sy", 1:length(tstrsplit(dt$Symbol, ""))) := tstrsplit( Symbol, "" )][]
# Name S1 S2 S3 Symbol Sy1 Sy2 Sy3 Sy4 Sy5
# 1: n_12 2.3 6.1 0 A A <NA> <NA> <NA> <NA>
# 2: n_13 3.4 3.7 0 ACM A C M <NA> <NA>
# 3: n_14 1.3 1.0 0 BN B N <NA> <NA> <NA>
# 4: n_23 2.0 4.1 0 NOPXY N O P X Y