在每个出现R的字符串一之后提取数据

时间:2017-11-16 04:21:59

标签: r regex read.table

我有这样的数据(命名光谱):

#Milk spectra: 1234
##XYDATA=(X++(Y..Y))
649.025085449219 
667.675231457819
686.325377466418 
##XYDATA=(X++(Y..Y))
723.625669483618 
742.275815492218 
760.925961500818 
##XYDATA=(X++(Y..Y))
872.826837552417 
891.476983561017 
910.127129569617
928.777275578216

在此数据中,每次都是字符串##XYDATA=(X++(Y..Y)),即每个不同动物的数据。 所以,我想拥有可以帮助将这个样本提取为3个数据的代码。

Animal 1: 3 lines after 1st '  ##XYDATA=(X++(Y..Y))'
Animal 2: 3 lines after 2nd '  ##XYDATA=(X++(Y..Y))'

等等。

我尝试了这行代码,但它只能帮助提取字符串'##XYDATA=(X++(Y..Y))'一起出现的所有时间的第1行。因此,它不符合我的期望,有三条线,并且在每次出现字符串后都有一个单独的数据。

bo<-data.frame(spectra$V1[which(spectra$V1 == '##XYDATA=(X++(Y..Y))')+1])

2 个答案:

答案 0 :(得分:0)

好的,我认为你可以沿着这些方向做点什么。我确信这可以更好,更有效,但可以将其作为字符向量阅读。 然后循环以展开它。但是,这假设总是有相同数量的度量,并且您可以识别字符值。

c_data<- c("split", 1, 2, 3, 
                   "split", 4, 5, 6)

y<- c_data == "split"

df_wide <- data.frame("animal"= character(), "v1" = numeric(), "v2" = numeric(), "v3" = numeric(),
                      stringsAsFactors = FALSE)
names(df_wide)<- c("animal", "v1", "v2", "v3")
x <- 0
for (i in 1:length(c_data)){

  if (y[i] == TRUE){
    x <- x +1
    df_wide[x,] <- rbind(c(c_data[i], c_data[i+1], c_data[i+2], c_data[i+3]))
  } 
}

产量

  animal v1 v2 v3
1  split  1  2  3
2  split  4  5  6

如果这是一次性事情,可能不值得尝试写一些更好的东西。如果它是一个持续的东西,那么你可能想看看使用你可能需要编写函数的apply函数。

答案 1 :(得分:0)

您可以使用splitmap执行以下任一操作:

library(dplyr)
library(purrr)

df %>%
  mutate(Animal = cumsum(grepl("##XYDATA=(X++(Y..Y))", V1, fixed = TRUE))) %>%
  split(.$Animal) %>%
  map(~slice(., -1) %>% mutate(V1 = as.numeric(V1))) %>%
  '['(-1)

这会创建一个指标变量Animal,按该指标拆分,删除每个数据帧的第一行,将V1转换为数字,最后删除列表的第一个元素。

您还可以执行以下操作:

df %>%
  mutate(Animal = cumsum(grepl("##XYDATA=(X++(Y..Y))", V1, fixed = TRUE))) %>%
  filter(!grepl("^#.*$", V1)) %>%
  mutate(V1 = as.numeric(V1)) %>%
  split(.$Animal)

这也会创建指标Animal,但它会在filter中显示所有包含#个符号的行,并在{之前}将V1转换为数字 / em>拆分为单独的数据帧。

<强>结果:

$`1`
# A tibble: 3 x 2
        V1 Animal
     <dbl>  <int>
1 649.0251      1
2 667.6752      1
3 686.3254      1

$`2`
# A tibble: 3 x 2
        V1 Animal
     <dbl>  <int>
1 723.6257      2
2 742.2758      2
3 760.9260      2

$`3`
# A tibble: 4 x 2
        V1 Animal
     <dbl>  <int>
1 872.8268      3
2 891.4770      3
3 910.1271      3
4 928.7773      3

注意:

这里我假设#Milk spectra: 1234也是列中的一行,因此最后是子集。

数据:

df = read.table(textConnection("'#Milk spectra: 1234'
                ##XYDATA=(X++(Y..Y))
                649.025085449219 
                667.675231457819
                686.325377466418 
                ##XYDATA=(X++(Y..Y))
                723.625669483618 
                742.275815492218 
                760.925961500818 
                ##XYDATA=(X++(Y..Y))
                872.826837552417 
                891.476983561017 
                910.127129569617
                928.777275578216"),comment.char = "", stringsAsFactors = FALSE)