[英]r - convert single column data frame to data frame with rows based on one fixed text
更新1
鏈接實際數據集,因為為示例數據提供的解決方案對我而言不可行。
鏈接: https : //app.box.com/s/65j1enr13pi51i44mfrymccklw1artot
請注意, LOT
是行標記的結尾。
-
我的數據框如下所示(單列):
D
2
f
h
k
END_ROW_WORD
k
1
2
END_ROW_WORD
e
g
j
2
k
END_ROW_WORD
我想將其轉換為以下格式:
如您所見,有一個特定的單詞(END_ROW_WORD)標記該行的結尾。
這是與Alejandro相似的方法,但是使用split
而不是for
循環:
colstarts <- diff(c(0, which(df == "END_ROW_WORD")))
rows <- split(df[[1]], rep(1:length(colstarts), colstarts))
rows <- lapply(rows, `length<-`, max(lengths(rows)))
as.data.frame(do.call(rbind, rows))
沒有for
-loops,但是有stringr
解決方案
library(stringr)
new_text <- str_c(df$V1, collapse = " ")
new_text <- str_replace_all(new_text, "END_ROW_WORD", "END_ROW_WORD\n")
read.table(text = new_text, fill = T)
# V1 V2 V3 V4 V5 V6
# 1 D 2 f h k END_ROW_WORD
# 2 k 1 2 END_ROW_WORD
# 3 e g j 2 k END_ROW_WORD
數據
df <-
structure(list(V1 = structure(c(3L, 2L, 6L, 8L, 10L, 5L, 10L, 1L, 2L, 5L, 4L, 7L, 9L, 2L, 10L, 5L),
.Label = c("1", "2", "D", "e", "END_ROW_WORD", "f", "g", "h", "j", "k"),
class = "factor")),
.Names = "V1", class = "data.frame", row.names = c(NA, -16L))
這可能不是最好的方法,但是可以
pos_help = which(grepl("END_ROW_WORD",data))
d = list()
for(i in 1:length(pos_help)){
if(i == 1){
d[[i]] = data[1:pos_help[1]]
} else {
d[[i]] = data[(pos_help[i-1]+1):pos_help[i]]
}
}
dataFrame = do.call(rbind,lapply(d, "length<-", max(lengths(d))))
首先,在每個"END_ROW_WORD"
標記之后放置換行符"\\n"
,然后將結果粘貼到長字符串中。
然后,它使用read.table
從文本連接中讀取數據。
end <- "END_ROW_WORD"
inx <- c(0, grep(end, dat[[1]]))
s <- NULL
for(i in seq_along(inx)[-1]){
s <- c(s, dat[[1]][(inx[(i - 1)] + 1):inx[i]], "\n")
}
con <- textConnection(paste(s, collapse = " "))
result <- read.table(con, fill = TRUE)
close(con)
result
# V1 V2 V3 V4 V5 V6
#1 D 2 f h k END_ROW_WORD
#2 k 1 2 END_ROW_WORD
#3 e g j 2 k END_ROW_WORD
數據。
dat <-
structure(list(V1 = c("D", "2", "f", "h", "k", "END_ROW_WORD",
"k", "1", "2", "END_ROW_WORD", "e", "g", "j", "2", "k", "END_ROW_WORD"
)), .Names = "V1", class = "data.frame", row.names = c(NA, -16L
))
編輯。
OP對該問題進行編輯后,我修改了代碼,以查看該文件是否可以正確讀取到data.frame
。 主要困難在於該文件具有許多不可打印的字符,而read.table
在到達文件末尾時遇到了麻煩。
積分這個問題的解決去接受的答案在read.csv警告“引用的字符串內EOF”防止文件的完整閱讀 。 我贊成這個問題和那個答案。
積分也必須給予@kath,在回答使用字符串替換把換行字符作為EOL標志的想法比我丑更好for
上述循環。 與kath不同,我僅使用base R
,我認為沒有必要加載外部軟件包。
現在修改代碼。
# Use this first pattern if AUCTION also marks the end of a row
#pattern <- "(^LOT|^AUCTION)"
pattern <- "(^LOT)"
dat <- readLines("data_.csv")
s <- gsub("[[:cntrl:]]", "", dat)
s <- sub(pattern, "\\1\n", s)
con <- textConnection(paste(s, collapse = "\t"))
result <- read.table(con, sep = "\t", fill = TRUE, quote = "", row.names = NULL)
close(con)
head(result)
tail(result)
str(result)
我以為會有一些空行,所以我用下面的代碼檢查了一下。
#
# See if there are any empty rows
#
empty <- apply(result, 1, function(x) nchar(trimws(paste0(x, collapse = ""))) == 0)
sum(empty)
#[1] 0
沒有循環,但是使用map和split...。(因為為什么不:p)
library(tidyverse)
df <- tibble(x=c(
"D",
"2",
"f",
"h",
"k",
"END_ROW_WORD",
"k",
"1",
"2",
"END_ROW_WORD",
"e",
"g",
"j",
"2",
"k",
"END_ROW_WORD"
)
)
split(df,cut(1:16,breaks=c(0,which(df == "END_ROW_WORD")))) %>%
map_dfc(~rbind(.x,tibble(x=rep(NA,(6-nrow(.x)))))) %>%
t() %>% as.data.frame()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.