将连续数据展开为R中的一行

将连续数据展开为R中的一行,r,dataframe,plyr,R,Dataframe,Plyr,我有一个软件,可以生成宽度有限的实验数据,这样在最终的csv中,一串数据点将被包装成一系列限制为4列宽的行,而不是每个变量(下面的a和B)一行,这是我需要的形式。(下面是示例csv) 在实际数据中,这让我每天要处理大约53000行,因此我想知道是否有一个函数允许我将给定的数据子集(每个变量)展开或重新标注为单行。在上面的示例中,变量A后面的数字将组合成一行,同时保持顺序(即1,3,3,2,5…),B也是如此,以此类推 根据请求,dput输出将生成上述简化示例 structure(list(V1

我有一个软件,可以生成宽度有限的实验数据,这样在最终的csv中,一串数据点将被包装成一系列限制为4列宽的行,而不是每个变量(下面的a和B)一行,这是我需要的形式。(下面是示例csv)

在实际数据中,这让我每天要处理大约53000行,因此我想知道是否有一个函数允许我将给定的数据子集(每个变量)展开或重新标注为单行。在上面的示例中,变量A后面的数字将组合成一行,同时保持顺序(即1,3,3,2,5…),B也是如此,以此类推

根据请求,dput输出将生成上述简化示例

 structure(list(V1 = structure(c(2L, 1L, 1L, 1L, 1L, 3L), .Label = c("", 
 "A", "B"), class = "factor"), V2 = c(1L, 5L, 9L, 13L, 17L, 1L
 ), V3 = c(2L, 6L, 10L, 14L, 18L, 2L), V4 = c(3L, 7L, 11L, 15L, 
 19L, 3L), V5 = c(4L, 8L, 12L, 16L, 20L, 4L)), .Names = c("V1", 
 "V2", "V3", "V4", "V5"), row.names = c(NA, 6L), class = "data.frame")

这有点难看,但这是我想到的第一个总体战略:

library(zoo)
library(plyr)
dat$V1 <- na.locf(dat$V1)
> ddply(dat,.(V1),function(x) c(t(as.matrix(x[,-1]))))
  V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20
1  1  3  3  2  5  6  7  8  9  10  11  12  13   1  15   6  17   1   2  20
2  1  2  3  7  7  6  7  8  9  10  11  12  13  15  15  16  17  18   3   2
图书馆(动物园)
图书馆(plyr)
dat$V1 ddply(dat,.(V1),函数(x)c(t)(如矩阵(x[,-1]))
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20
1  1  3  3  2  5  6  7  8  9  10  11  12  13   1  15   6  17   1   2  20
2  1  2  3  7  7  6  7  8  9  10  11  12  13  15  15  16  17  18   3   2
假设您将数据读入名为
dat
的对象,并使用
na.strings=“”
。您可以在之后添加
A
B
变量信息,或者可能将其填充到匿名
ddply
函数中


可能有一种方法可以直接使用dcast对其进行重塑,但我想不出一种方法。

您可以使用外部工具对文件进行预处理

read.csv(pipe("sed -e :a -e '$!N;s/\\n,//;ta' -e 'P;D' file.txt"), head=FALSE)
基本上,
file.txt
首先由unix工具
sed
处理,该工具执行搜索和替换,并将新内容返回到R。我改编的正则表达式用于执行以下任务:

  If a line begins with a comma, append it to the previous line 
  and replace the "," with nothing

Edit(eddi——注意:这在Mac OS上似乎不起作用)下面是
sed如何解析以下命令:

read.csv(pipe("sed ':a; N; s/\\n,/,/; t a; P; D' file.txt"), head=FALSE)

:a       # label (named "a") we're going to come back to
N        # read in the next line into pattern space, together with the newline character
s/\n,/,/ # if there is a newline followed by comma, delete the newline
t a      # go back to "a" and repeat until the above match fails (t stands for test)
P        # print everything in pattern space up to and including last \n
D        # delete everything in pattern space up to and including last \n

你不喜欢仪器制造商吗

这里有一种方法,我不认为它很完美,因为我不能完全测试所有数据,但你可以

编辑:更新功能

cleanData <- function(df) {
    good <- c() # holds indices of lines that start a row in the final data set
        # Find the 'starter' rows
    for (n in 1:nrow(df)) {
        if (df[n,1] != "") good <- c(good,n)
        }

    # Now go back and put it back together
    # Get one row in 1st to set dimensions

    newDat <- data.frame(mydat = df[(good[1]:(good[2])-1),])
    offset <- nrow(newDat)-1
    data <- as.numeric(t(as.matrix(newDat[,-1])))
    label <- df[1,1]
    newDat <- data.frame(data)
    names(newDat) <- label
    #print(newDat) # OK

    # now do them all
    for (n in 2:length(good)) {
        use <- good[n]:(good[n] + offset)
        data <- as.numeric(t(as.matrix(df[use,-1])))
        label <- df[good[n],1]
        newCol <- data.frame(data)
        names(newCol) <- label
        newDat <- cbind(newDat, newCol)
        }

    newDat
    }

grep、paste和read.table在这里非常方便

# read in your data raw
X <- read.table("file")

# Any line that does NOT start with a comma, add a line break, 
# then re-read with read.table
read.table(text=paste(ifelse(grepl("^,", X), X, paste("\n", X)), collapse=""), sep=",")

这是另一个基本的R解决方案。它使用
gsub()


可以用
read.csv
读入此文件吗?如果可以,您可以
dput
它为您提供了什么?如果它能工作的话,我猜第2-5行的开头会有一个NA,等等。另外,尝试
readLines
dput(head(data)
在你的问题中也是如此。第二种方法肯定会奏效。任何一种方法都需要编写一个小函数来恢复数据的完整性。听起来像是真实世界!而且,真实数据行的开头总是大写字母吗?嗯,我对R很陌生,所以我不确定我会遵循。我通常使用read.csv.Gene读取数据将变量标题(始终大写为“A:,B:,…”的标题)之间的所有行合并显示为空。dput是否依赖于另一个库,还是它是read.csv中的一个参数?如果已将数据读入名为
tst
的变量,请执行
dput(head(tst))
并将结果复制到上面的问题中。这向我们展示了数据的结构,并提供了一小部分数据进行测试。好的,这听起来很合理。每个变量的数组长度始终相同,未使用的位置显示为0填充。它们也总是按照相同的顺序排列,因此如果我必须为第n行重新附加变量标题艾姆斯:这不应该是个问题。考虑到我对R和编程一般来说是多么的陌生,你能帮我解压一下语法吗?我一直在跟进,直到ddply。我以前尝试过使用ddply,但运气不好,因为我似乎找不到对许多参数的直观的、非程序员友好的解释。我特别记得我不明白调用函数(x)位。谢谢。@user2510207
ddply
的第三个参数是应用于每个“块”的函数。您可以传递现有函数的名称,也可以像我在这里所做的那样定义一个新函数“inline”。这被称为“匿名函数”因为它只存在于
ddply
调用的上下文中。好吧,很酷。那么定义c(t)的函数(如矩阵(x[,-1)以及它是如何完成任务的呢?@user2510207它只接受值和(1)从数据帧到矩阵的转换,减去第一列,(2)转置矩阵,和(3)将值展平为单个向量。转置是必要的,因为R按列而不是按行存储矩阵。我编写的函数本质上是Joran描述的手动版本。我喜欢这些函数,但它们从来都不是透明的!如果年幼的孩子,也许他们会变得更自然;毕竟它与sm没有太大区别ileys和sms语言。grep人站了起来。我恐怕你已经失去了我。我不明白如何使用它,或者除了read.csv:-/。检查结果的顺序:要么你或我解析错误。或者不管怎样,我发现OP的
dput
和问题中的数据之间有差异。我使用了e,你用了另一个。@BryanHanson,我用了OP顶部的数据集,你是对的,看起来它们是不同的。Hanks Ricardo,我现在有很多选择要尝试。感谢Bryan,这是一段需要编写帮助的代码。我将尝试这些方法。这是一个很好的难题,而不是我正在做的工作该做了!很好:精练,但直截了当。我喜欢这个问题的答案范围。非常聪明。相比之下,我的答案太粗野了!我不知道有一个
text
参数指向
read.table
'data.frame':   20 obs. of  2 variables:
 $ A: num  1 2 3 4 5 6 7 8 9 10 ...
 $ B: num  1 2 3 4 NA NA NA NA NA NA ...
# read in your data raw
X <- read.table("file")

# Any line that does NOT start with a comma, add a line break, 
# then re-read with read.table
read.table(text=paste(ifelse(grepl("^,", X), X, paste("\n", X)), collapse=""), sep=",")
  V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21  
1  A  1  3  3  2  5  6  7  8   9  10  11  12  13   1  15   6  17   1   2  20  
2  B  1  2  3  7  7  6  7  8   9  10  11  12  13  15  15  16  17  18   3   2
txt = readLines("file.txt")

# Join into one long string with newlines.
txt_long = paste(txt, collapse="\n")

# Remove newlines directly preceding a comma.
newtxt = gsub("\\n,", ",", txt_long)

read.table(text=newtxt, sep=",")
#   V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21
# 1  A  1  3  3  2  5  6  7  8   9  10  11  12  13   1  15   6  17   1   2  20
# 2  B  1  2  3  7  7  6  7  8   9  10  11  12  13  15  15  16  17  18   3   2