基于列表结构模式创建新列表
Create New Lists Based on List Structure Pattern
我有一些数据如下所示:
dat <- c("Sales","Jim","Halpert","","",
"Reception","Pam","Beasley","","",
"Not.Manager","Dwight","Schrute","Bears","Beets","BattlestarGalactica","","",
"Manager","Michael","Scott","","")
每个数据“块”都是连续的,中间有一些空白。我想将数据转换成如下所示的列表列表:
iwant <- c(
c("Sales","Jim","Halpert"),
c("Reception","Pam","Beasley"),
c("Not.Manager","Dwight","Schrute","Bears","Beets","BattlestarGalactica"),
c("Manager","Michael","Scott")
)
建议?我正在使用 rvest 和 stringi。我不想添加更多包。
我建议采用下一种方法。您最终会得到一个数据框,其中的变量格式与您想要的格式类似:
#Split chains
L1 <- strsplit(paste0(dat,collapse = " "),split = " ")
#Split vectors from each chain
L2 <- lapply(L1[[1]],function(x) strsplit(trimws(x),split = " "))
#Format
L2 <- lapply(L2,as.data.frame)
#Remove zero dim data
L2[which(lapply(L2,nrow)==0)]<-NULL
#Format names
L2 <- lapply(L2,function(x) {names(x)<-'v';return(x)})
#Transform to dataframe
D1 <- as.data.frame(do.call(cbind,L2))
#Rename
names(D1) <- paste0('V',1:dim(D1)[2])
#Remove recycled values
D1 <- as.data.frame(apply(D1,2,function(x) {x[duplicated(x)]<-NA;return(x)}))
输出:
V1 V2 V3 V4
1 Sales Reception Not.Manager Manager
2 Jim Pam Dwight Michael
3 Halpert Beasley Schrute Scott
4 <NA> <NA> Bears <NA>
5 <NA> <NA> Beets <NA>
6 <NA> <NA> BattlestarGalactica <NA>
您可以将 rle
、split
与 lapply
一起使用:
lapply(split(dat, with(rle(dat != ''),
rep(cumsum(values), lengths))), function(x) x[x!= ''])
#$`1`
#[1] "Sales" "Jim" "Halpert"
#$`2`
#[1] "Reception" "Pam" "Beasley"
#$`3`
#[1] "Not.Manager" "Dwight" "Schrute" "Bears" "Beets"
#[6] "BattlestarGalactica"
#$`4`
#[1] "Manager" "Michael" "Scott"
rle
部分在 :
上创建组到 split
with(rle(dat != ''), rep(cumsum(values), lengths))
#[1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 3 3 3 4 4 4 4 4
在 split
之后,我们使用 lapply
从每个列表中删除所有空元素。
我有一些数据如下所示:
dat <- c("Sales","Jim","Halpert","","",
"Reception","Pam","Beasley","","",
"Not.Manager","Dwight","Schrute","Bears","Beets","BattlestarGalactica","","",
"Manager","Michael","Scott","","")
每个数据“块”都是连续的,中间有一些空白。我想将数据转换成如下所示的列表列表:
iwant <- c(
c("Sales","Jim","Halpert"),
c("Reception","Pam","Beasley"),
c("Not.Manager","Dwight","Schrute","Bears","Beets","BattlestarGalactica"),
c("Manager","Michael","Scott")
)
建议?我正在使用 rvest 和 stringi。我不想添加更多包。
我建议采用下一种方法。您最终会得到一个数据框,其中的变量格式与您想要的格式类似:
#Split chains
L1 <- strsplit(paste0(dat,collapse = " "),split = " ")
#Split vectors from each chain
L2 <- lapply(L1[[1]],function(x) strsplit(trimws(x),split = " "))
#Format
L2 <- lapply(L2,as.data.frame)
#Remove zero dim data
L2[which(lapply(L2,nrow)==0)]<-NULL
#Format names
L2 <- lapply(L2,function(x) {names(x)<-'v';return(x)})
#Transform to dataframe
D1 <- as.data.frame(do.call(cbind,L2))
#Rename
names(D1) <- paste0('V',1:dim(D1)[2])
#Remove recycled values
D1 <- as.data.frame(apply(D1,2,function(x) {x[duplicated(x)]<-NA;return(x)}))
输出:
V1 V2 V3 V4
1 Sales Reception Not.Manager Manager
2 Jim Pam Dwight Michael
3 Halpert Beasley Schrute Scott
4 <NA> <NA> Bears <NA>
5 <NA> <NA> Beets <NA>
6 <NA> <NA> BattlestarGalactica <NA>
您可以将 rle
、split
与 lapply
一起使用:
lapply(split(dat, with(rle(dat != ''),
rep(cumsum(values), lengths))), function(x) x[x!= ''])
#$`1`
#[1] "Sales" "Jim" "Halpert"
#$`2`
#[1] "Reception" "Pam" "Beasley"
#$`3`
#[1] "Not.Manager" "Dwight" "Schrute" "Bears" "Beets"
#[6] "BattlestarGalactica"
#$`4`
#[1] "Manager" "Michael" "Scott"
rle
部分在 :
split
with(rle(dat != ''), rep(cumsum(values), lengths))
#[1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 3 3 3 4 4 4 4 4
在 split
之后,我们使用 lapply
从每个列表中删除所有空元素。