如何从数据框列中提取信息以生成新的数据框

时间:2015-04-11 08:01:24

标签: r format strptime

我有一个数据框,第一列Raw Data读取如下:

Raw Data
USGS    162        1994-10-15      14      A
USGS    162        1994-10-16      49      A
USGS    162        1994-10-17      39      A
......

我试图创建一个现在有两列而不是1的新数据框。第一列有日期,第二列有整数值,所以它看起来像这样:

Date        Integer
1994-10-15  14

我知道你可以使用strptime()和format()来提取年,月,日但是当你在单元格中有额外的数字和字符时,我不确定这是如何工作的。感谢。

3 个答案:

答案 0 :(得分:3)

您可以使用read.table

 res <- read.table(text=df$RawData, header=FALSE, sep='', 
   colClasses=c(NA, NA, 'Date', 'integer'), col.names=c('', '', 
            'Date', 'Integer', ''))[3:4]
 res
 #        Date Integer
 #1 1994-10-15      14
 #2 1994-10-16      49
 #3 1994-10-17      39

或使用cSplit中的splitstackshape。之后可以使用as.Date

将“日期”列类更改为“日期”
 library(splitstackshape)
 setnames(cSplit(df, 'RawData', sep=' ', type.convert=TRUE)[,3:4,
              with=FALSE], c('Date', 'Integer'))[]

或者

 library(tidyr)
 extract(df, 'RawData', into= c('Date', 'Integer'), 
         '\\S*\\s*\\S*\\s*(\\S*)\\s*(\\S*).*', convert=TRUE)

或者

 library(data.table)#v1.9.5+
 setnames(setDT(df)[, tstrsplit(RawData, ' +', 
            type.convert=TRUE)[3:4]], c('Date', 'Integer'))[]

注意:来自@ bgoldst帖子的'df'

答案 1 :(得分:1)

这是一种方法:

df <- data.frame(RawData=c('USGS    162        1994-10-15      14      A','USGS    162        1994-10-16      49      A','USGS    162        1994-10-17      39      A'), stringsAsFactors=F );
df;
##                                        RawData
## 1 USGS    162        1994-10-15      14      A
## 2 USGS    162        1994-10-16      49      A
## 3 USGS    162        1994-10-17      39      A
df2 <- do.call(rbind, lapply(strsplit(df$RawData,'\\s+'), function(x) data.frame(Date=as.Date(x[3]), Integer=as.integer(x[4]) ) ) );
df2;
##         Date Integer
## 1 1994-10-15      14
## 2 1994-10-16      49
## 3 1994-10-17      39

由于您的日期已经是YYYY-mm-dd格式,因此实际上不需要strptime()format()或其他任何内容;您可以使用as.Date()将字符串直接强制转换为日期类型。

唯一的挑战是从包含日期和整数值的输入字符串中提取相关的文本片段。我假设输入数据总是以空格分隔,因为它在您的问题中显示出来。我的解决方案将输入字符串拆分为空间strsplit(df$RawData,'\\s+')上的字段。这导致了一个字符向量列表。然后lapply()调用遍历每个向量,并将两个字段提取并强制转换为Date和整数类型,并组合成一行data.frame。最后,do.call(rbind, ... )将所有这些单行data.frames组合成一个data.frame。

答案 2 :(得分:1)

gsub的乐趣解决方案(如果需要,将列转换为带as.integer的整数):

x = unlist(df)

data.frame(
   Date = gsub(".*(\\d{4}-\\d{2}-\\d{2}).*","\\1",x),
   Integer = gsub(".*(\\d{4}-\\d{2}-\\d{2})[ ]+(\\d+).*","\\2",x)
)

#               Date Integer
#RawData1 1994-10-15      14
#RawData2 1994-10-16      49
#RawData3 1994-10-17      39

数据:

df = structure(list(RawData = c("USGS    162        1994-10-15      14      A", 
"USGS    162        1994-10-16      49      A", "USGS    162        1994-10-17      39      A"
)), .Names = "RawData", row.names = c(NA, -3L), class = "data.frame")