如何从数据框列中提取信息以制作新的数据框

How to extract information from a data frame column to make a new data frame

我有一个数据框,第一列原始数据如下所示:

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

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

Date        Integer
1994-10-15  14

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

这是一种方法:

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().

将字符串直接强制转换为 Date 类型

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

您可以使用 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

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

更改为 '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'))[]

注意:'df' 来自@bgoldst 的 post

使用 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")