R:如何将列表拆分为 AM/PM
R: how to split list into AM/PM
调查中的时间戳将我的所有数据分组到 StartTime 下的一列中,但我需要将我的数据分成 AM 和 PM 组。
例如,现在我的数据看起来像
8:37 PM
3:58 PM
10:22 AM
2:48 PM
6:33 PM
7:10 AM
10:59 AM
但我需要把它分成
8:37 PM 10:22 AM
3:58 PM 7:10 AM
2:48 PM 10:59 AM
6:33 PM
关于如何做到这一点有什么想法吗?谢谢
您可以使用split
split(df1, grepl('PM', df1$StartTime))
如果你需要得到一个有两列的data.frame
lst <- split(df1$StartTime, grepl('PM', df1$StartTime))
setNames(data.frame(lapply(lst, `length<-`, max(lengths(lst)))),
c('AM', 'PM'))
# AM PM
#1 10:22 AM 8:37 PM
#2 7:10 AM 3:58 PM
#3 10:59 AM 2:48 PM
#4 <NA> 6:33 PM
或
library(data.table)#v1.9.5+
dcast(setDT(df1)[, group:= c('AM', 'PM')[grepl('PM', StartTime)+1L]][,
N:=1:.N, group], N~group, value.var='StartTime')
# N AM PM
#1: 1 10:22 AM 8:37 PM
#2: 2 7:10 AM 3:58 PM
#3: 3 10:59 AM 2:48 PM
#4: 4 NA 6:33 PM
或使用dplyr/tidyr
library(dplyr)
library(tidyr)
df1 %>%
extract(StartTime, into='AMPM', '[^ ]+\s+([^ ]+)', remove=FALSE) %>%
group_by(AMPM) %>%
mutate(n=row_number()) %>%
spread(AMPM, StartTime)
数据
df1 <- structure(list(StartTime = c("8:37 PM", "3:58 PM", "10:22 AM",
"2:48 PM", "6:33 PM", "7:10 AM", "10:59 AM")), .Names = "StartTime",
class = "data.frame", row.names = c(NA, -7L))
这是一个使用 substring()
, nchar()
, within()
, ave()
, seq_along()
, and reshape()
的解决方案:
df <- data.frame(StartTime=c('8:37 PM','3:58 PM','10:22 AM','2:48 PM','6:33 PM','7:10 AM','10:59 AM'),stringsAsFactors=F);
reshape(within(df,{time<-substring(StartTime,nchar(StartTime)-1);id<-ave(time,time,FUN=seq_along);}),dir='w')[-1];
## StartTime.PM StartTime.AM
## 1 8:37 PM 10:22 AM
## 2 3:58 PM 7:10 AM
## 4 2:48 PM 10:59 AM
## 5 6:33 PM <NA>
这假设 AM/PM 子字符串始终是输入时间字符串的最后两个字符。
调查中的时间戳将我的所有数据分组到 StartTime 下的一列中,但我需要将我的数据分成 AM 和 PM 组。
例如,现在我的数据看起来像
8:37 PM
3:58 PM
10:22 AM
2:48 PM
6:33 PM
7:10 AM
10:59 AM
但我需要把它分成
8:37 PM 10:22 AM
3:58 PM 7:10 AM
2:48 PM 10:59 AM
6:33 PM
关于如何做到这一点有什么想法吗?谢谢
您可以使用split
split(df1, grepl('PM', df1$StartTime))
如果你需要得到一个有两列的data.frame
lst <- split(df1$StartTime, grepl('PM', df1$StartTime))
setNames(data.frame(lapply(lst, `length<-`, max(lengths(lst)))),
c('AM', 'PM'))
# AM PM
#1 10:22 AM 8:37 PM
#2 7:10 AM 3:58 PM
#3 10:59 AM 2:48 PM
#4 <NA> 6:33 PM
或
library(data.table)#v1.9.5+
dcast(setDT(df1)[, group:= c('AM', 'PM')[grepl('PM', StartTime)+1L]][,
N:=1:.N, group], N~group, value.var='StartTime')
# N AM PM
#1: 1 10:22 AM 8:37 PM
#2: 2 7:10 AM 3:58 PM
#3: 3 10:59 AM 2:48 PM
#4: 4 NA 6:33 PM
或使用dplyr/tidyr
library(dplyr)
library(tidyr)
df1 %>%
extract(StartTime, into='AMPM', '[^ ]+\s+([^ ]+)', remove=FALSE) %>%
group_by(AMPM) %>%
mutate(n=row_number()) %>%
spread(AMPM, StartTime)
数据
df1 <- structure(list(StartTime = c("8:37 PM", "3:58 PM", "10:22 AM",
"2:48 PM", "6:33 PM", "7:10 AM", "10:59 AM")), .Names = "StartTime",
class = "data.frame", row.names = c(NA, -7L))
这是一个使用 substring()
, nchar()
, within()
, ave()
, seq_along()
, and reshape()
的解决方案:
df <- data.frame(StartTime=c('8:37 PM','3:58 PM','10:22 AM','2:48 PM','6:33 PM','7:10 AM','10:59 AM'),stringsAsFactors=F);
reshape(within(df,{time<-substring(StartTime,nchar(StartTime)-1);id<-ave(time,time,FUN=seq_along);}),dir='w')[-1];
## StartTime.PM StartTime.AM
## 1 8:37 PM 10:22 AM
## 2 3:58 PM 7:10 AM
## 4 2:48 PM 10:59 AM
## 5 6:33 PM <NA>
这假设 AM/PM 子字符串始终是输入时间字符串的最后两个字符。