R语言 通过可变数量的空格将字符串分隔到表中

9avjhtql  于 2023-06-27  发布在  其他
关注(0)|答案(2)|浏览(145)

我有一些数据像这样导入到R中(字符串):

> dput(my_data)
c("S Leistung Sub Text Ergebnis Einheit Normal Auffällig Katalog Datum Zeit Kommentar ", 
"   APOA_S      Apo A1   1.11   g/l   1.04 - 2.02      01   30.03.2023   06:56   ", 
"  ", "", "   APOB_S      Apo B   1.09   g/l   0.66 - 1.33      01   30.03.2023   06:56   ", 
"  ", "", "   B-BA_E      Basophile Granulozyten absolut   0.04   exp 9/l   0 - 0.1      01   27.03.2023   11:56   ", 
"  ", "", "   B-DBB_E      Differentialblutbild   ·            01   27.03.2023   11:45   ", 
"  ")

有比这里显示的更多的行。我需要将它以表格的形式呈现如下:

S  Leistung  Sub  Text    Ergebnis  Einheit  ...   ...
   APOA_S         Apo A1  1.11      g/l
   APOB_S         Apo B1  1.09      g/l
   ...
   ...

我只需要名为“Leistung”和“Ergebnis”的列,但是所有这些列的输出也很好!
问题是我的数据:

  • 它不使用常规分隔符
  • 唯一的“分隔符”,我可以确定是多个空格(2 - 15个空格)
  • 但是,一个值中可能会出现一个空格(如“Apo A1”),不应作为分隔符。
  • 在标题中,只有1个空格用作分隔符
  • 固定宽度不起作用。
  • 名为“Sub”的列总是空的。

有没有办法用(多个)空格分隔它?如何处理空的“子”列?

ttygqcqt

ttygqcqt1#

更新

由于缺少数据而没有明确的分隔符,很难分配丢失的数据,但根据OP,他不需要所有数据,因此这里有一个获得有限列的解决方案。

data <- do.call(rbind, lapply(stri_trim_both(my_data)[-1], \(line) {
  as.data.frame(t(na.omit(strsplit(line, "\\s{2,}")[[1]])[1:3]))
}))

# Just hardcode them
names(data) <- c("Leistung", "Text", "Ergebnis")

data

#   Leistung                           Text Ergebnis
# 1   APOA_S                         Apo A1     1.11
# 2   APOB_S                          Apo B     1.09
# 3  B-DBB_E           Differentialblutbild        ·
# 4   B-BA_E Basophile Granulozyten absolut     0.04

更新2

查看数据-如果您始终拥有前2列和后3列,并且缺失的数据要么是一个点,要么根本缺失,则我们可以这样做以获得完整的数据。

data <- do.call(rbind, lapply(stri_trim_both(my_data)[-1], \(line) {
  
  v <- strsplit(line, "\\s{2,}")[[1]]
  l <- length(v)
  if (l > 0) {
    if (l < 8) {
      v <- c(v[1:2], rep(NA, 3), v[(l-2):l])
    }
    as.data.frame(t(v))
  }
  
}))

names(data) <- c("Leistung", "Text", "Ergebnis", "Einheit", "Normal_Auffällig", "Katalog", "Datum", "Zeit")

资料

Leistung                           Text Ergebnis Einheit Normal_Auffällig Katalog      Datum  Zeit
1   APOA_S                         Apo A1     1.11     g/l      1.04 - 2.02      01 30.03.2023 06:56
2   APOB_S                          Apo B     1.09     g/l      0.66 - 1.33      01 30.03.2023 06:56
3  B-DBB_E           Differentialblutbild     <NA>    <NA>             <NA>      01 27.03.2023 11:45
4   B-BA_E Basophile Granulozyten absolut     0.04 exp 9/l          0 - 0.1      01 27.03.2023 11:56

test.txt

S Leistung Sub Text Ergebnis Einheit Normal Auffällig Katalog Datum Zeit Kommentar 
   APOA_S      Apo A1   1.11   g/l   1.04 - 2.02      01   30.03.2023   06:56   

   APOB_S      Apo B   1.09   g/l   0.66 - 1.33      01   30.03.2023   06:56  

   B-DBB_E      Differentialblutbild   ·            01   27.03.2023   11:45             
  B-BA_E      Basophile Granulozyten absolut   0.04   exp 9/l   0 - 0.1      01   27.03.2023   11:56

原始答案

我假设你以某种方式读取了一个文本文件,让我们模拟一下。
test.txt

S Leistung Sub Text Ergebnis Einheit Normal Auffällig Katalog Datum Zeit Kommentar 
   APOA_S      Apo A1   1.11   g/l   1.04 - 2.02      01   30.03.2023   06:56   
   APOB_S      Apo B   1.09   g/l   0.66 - 1.33      01   30.03.2023   06:56

当我们读取您的数据时,您或多或少会得到显示为my_data的内容

my_data <- readLines("test.txt")

my_data

[1] "S Leistung Sub Text Ergebnis Einheit Normal Auffällig Katalog Datum Zeit Kommentar " "   APOA_S      Apo A1   1.11   g/l   1.04 - 2.02      01   30.03.2023   06:56   "   
[3] "   APOB_S      Apo B   1.09   g/l   0.66 - 1.33      01   30.03.2023   06:56   "

从那里我们采取两个步骤,我在这里做了一些猜测的命名和数量的数据记录,我发现在您的行。所以我删除了S,Sub和Kommentar,我猜Normal和Auffällig可以合并表示这两个值。如果我错了,你可以调整一下。

library(stringi) # used for some replacements

header <- stri_replace_all_fixed(my_data[1], "Normal Auffällig", "Normal_Auffällig")
header <- strsplit(header, " ")[[1]]
header <- header[!header %in% c("S", "Sub", "Kommentar")]

我猜这些是要“保留”的

[1] "Leistung"         "Text"             "Ergebnis"         "Einheit"          "Normal_Auffällig" "Katalog"          "Datum"            "Zeit"

然后我们抓取你的数据,它从没有第一个标题行开始,我们首先左右修剪它,然后按多个空格分割。

data <- do.call(rbind, lapply(stri_trim_both(my_data)[-1], \(line) {
  as.data.frame(t(strsplit(line, "\\s{2,}")[[1]]))
}))

现在添加标题

names(data) <- header

最后的结果

data

  Leistung   Text Ergebnis Einheit Normal_Auffällig Katalog      Datum  Zeit
1   APOA_S Apo A1     1.11     g/l      1.04 - 2.02      01 30.03.2023 06:56
2   APOB_S  Apo B     1.09     g/l      0.66 - 1.33      01 30.03.2023 06:56
42fyovps

42fyovps2#

这是一个开始:

## split on *two* spaces, trim white space, drop empty elements
x2 <- strsplit(d, "  ") |>
   sapply( trimws ) |> 
      sapply( function(x) x[nzchar(x)])
## drop empty rows
x3 <- x2[lengths(x2) > 0]
## skip header, take first four columns
x4 <- lapply(x3[-1], function(x) x[1:4])
## combine
do.call(rbind, x4)
[,1]      [,2]                             [,3]   [,4]     
[1,] "APOA_S"  "Apo A1"                         "1.11" "g/l"    
[2,] "APOB_S"  "Apo B"                          "1.09" "g/l"    
[3,] "B-BA_E"  "Basophile Granulozyten absolut" "0.04" "exp 9/l"
[4,] "B-DBB_E" "Differentialblutbild"           "·"    "01"

您仍然需要解析标题以提取列名;转换为数据框,并根据需要将列转换为数字;弄清楚第3-4行中的格式/结构是怎么回事;等等。

相关问题