我有一个包含
的数据框df
Date name score
12/09/2012 Mahesh\nRahul 120
13/09/2012 abc\nxyz\nrep 110
...........................
我试过这个以获得原子
name1=str_split(df[,2],"\n")
但不知道如何再次关联,使数据帧规范化的最佳方法是什么,以便我可以得到
df
Date name score
12/09/2012 Mahesh 120
12/09/2012 Rahul 120
13/09/2012 abc 110
13/09/2012 xyz 110
13/09/2012 rep 110
...........................
在R中规范化长数据帧的任何帮助。
修改
请注意,这只是一个可重现的示例,我的名称列中有多个名称,名称数量从一行到另一行不等。谢谢。
答案 0 :(得分:5)
这是一个R基础解决方案
> Names <- strsplit(df$name, "\n")
> n <- sapply(Names, length)
> data.frame(cbind(apply(df[,-2], 2, function(x) rep(x, n)),
name=unlist(Names)), row.names = NULL)[,c(1,3,2)]
Date name score
1 12/09/2012 Mahesh 120
2 12/09/2012 Rahul 120
3 13/09/2012 abc 110
4 13/09/2012 xyz 110
5 13/09/2012 rep 110
其中df
是:
> dput(df)
structure(list(Date = c("12/09/2012", "13/09/2012"), name = c("Mahesh\nRahul",
"abc\nxyz\nrep"), score = c(120, 110)), .Names = c("Date", "name",
"score"), row.names = c(NA, -2L), class = "data.frame")
答案 1 :(得分:2)
使用data.table
相对容易(显然很快)。
require( data.table )
dt <- data.table( df )
dt[ , list( name = unlist( strsplit( name , "\n" ) ) ) , by = list( Date , score ) ]
# Date score name
#1: 12/09/2012 120 Mahesh
#2: 12/09/2012 120 Rahul
#3: 13/09/2012 110 abc
#4: 13/09/2012 110 xyz
作为备注,我将df
作为以下数据(请注意character
类,而不是实际数据中出现的factor
类......
df <- read.delim( text = "Date name score
12/09/2012 'Mahesh\nRahul' 120
13/09/2012 'abc\nxyz' 110" ,
sep = "" , h = TRUE , quote = "\'" , stringsAsFactors = FALSE )
答案 2 :(得分:2)
要添加替代方案,您可以使用scan
轻松分隔字符串,rep
和cbind
以获得最终data.frame
df
# Date name score
# 1 12/09/2012 Mahesh\nRahul 120
# 2 13/09/2012 abc\nxyz\nrep 110
scan(text=as.character(df$name), what = "")
# Read 5 items
# [1] "Mahesh" "Rahul" "abc" "xyz" "rep"
cbind(df[rep(rownames(df),
sapply(gregexpr("\n", df$name), length)+1),
c("Date", "score")],
name = scan(text=as.character(df$name), what = ""))
# Date score name
# 1 12/09/2012 120 Mahesh
# 1.1 12/09/2012 120 Rahul
# 2 13/09/2012 110 abc
# 2.1 13/09/2012 110 xyz
# 2.2 13/09/2012 110 rep
read.table
也可用于拆分连续列:
read.table(text = as.character(df$name), sep = "\n", header = FALSE)
# V1
# 1 Mahesh
# 2 Rahul
# 3 abc
# 4 xyz
# 5 rep
答案 3 :(得分:1)
这里已有很好的答案,但这是基础R使用rle
和inverse.rle
函数的另一种方法。 @Jilber的基础R解决方案更优雅,但如果您的字符串有两个以上的名称,这种方式将起作用。
df <- read.table(text='Date name score
12/09/2012 "Mahesh\nRahul" 120
13/09/2012 "abc\nxyz\nrep" 110', header=TRUE, stringsAsFactors=FALSE)
ns <- strsplit(df$name, '\n')
result <- lapply(lapply(lapply(df, rle), `[[<-`, 'lengths', sapply(ns, length)), inverse.rle)
transform(data.frame(result), name=unlist(ns))
# Date name score
# 1 12/09/2012 Mahesh 120
# 2 12/09/2012 Rahul 120
# 3 13/09/2012 abc 110
# 4 13/09/2012 xyz 110
# 5 13/09/2012 rep 110