簡體   English   中英

r-根據一個固定的文本將單列數據幀轉換為帶有行的數據幀

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM