我有一个数字变量,DATE表示最后两个字符的日期MONTH和前一个或两个字符DAY.我想列分成单独的列的MONTH和DAY.
我可以使用以下R代码执行此操作.虽然我希望有一个更简单的regex解决方案.
my.data <- read.table(text = '
ID DATE VARX
A111 104 0
A111 204 1
A111 1004 4
A111 2004 4
B111 3004 2
C111 3004 3
C111 105 4
C111 1005 4
', header = TRUE, stringsAsFactors = FALSE)
# remove the last two characters of a string
my.data$DAY <- ifelse(nchar(my.data$DATE) == 3,
substr(my.data$DATE, nchar(my.data$DATE) - (nchar(my.data$DATE)-1), nchar(my.data$DATE) - (nchar(my.data$DATE)-1)),
substr(my.data$DATE, nchar(my.data$DATE) - (nchar(my.data$DATE)-1), nchar(my.data$DATE) - (nchar(my.data$DATE)-2)))
# keep the last two characters of a string
my.data$MONTH <- substr(my.data$DATE, (nchar(my.data$DATE)-1), nchar(my.data$DATE))
ID DATE VARX DAY MONTH
1 A111 104 0 1 04
2 A111 204 1 2 04
3 A111 1004 4 10 04
4 A111 2004 4 20 04
5 B111 3004 2 30 04
6 C111 3004 3 30 04
7 C111 105 4 1 05
8 C111 1005 4 10 05
Run Code Online (Sandbox Code Playgroud)
谢谢你的任何建议.
以下是一些替代方案.第一个是最简洁的.前两个只用底座R.
1)数字操作
transform(my.data, MONTH = DATE %% 100, DAY = DATE %/% 100)
Run Code Online (Sandbox Code Playgroud)
赠送:
ID DATE VARX MONTH DAY
1 A111 104 0 4 1
2 A111 204 1 4 2
3 A111 1004 4 4 10
4 A111 2004 4 4 20
5 B111 3004 2 4 30
6 C111 3004 3 4 30
7 C111 105 4 5 1
8 C111 1005 4 5 10
Run Code Online (Sandbox Code Playgroud)
2)sub 这给出与(1)中相同的结果.
spl <- function(x, replace) as.numeric(sub("(.*)(..)", replace, x))
transform(my.data, MONTH = spl(DATE, "\\2"), DAY = spl(DATE, "\\1"))
Run Code Online (Sandbox Code Playgroud)
3)strapply适用as.numeric于括号中的匹配部分并返回它.这给出了与(1)中相同的结果.
library(gsubfn)
spl <- function(x, rx) strapply(x, rx, as.numeric, simplify = TRUE)
transform(my.data, MONTH = spl(DATE, ".*(..)"), DAY = spl(DATE, "(.*).."))
Run Code Online (Sandbox Code Playgroud)
注意 它们都返回数字列,这似乎更合适,但如果你想改变那个添加 as.character(...)或适当sprintf的(1),省略as.numeric(2)或用as.numeric(3)替换c.
更新已 添加2和3并进行了一些改进.