使用 lubridate 和 if 语句进行日期操作

Date manipulation with lubridate and if-statement

我正在努力处理一些数据操作。我的数据表中的一列包含出生日期,但有一个位置的值相差 100 年。

我制作了一个示例小数据框来解释我的问题:巴黎/柏林的日期是正确的,我只想更改以伦敦为位置的那些行的日期(对于此示例,从 2028-3-25到 1928-3-25).

library(lubridate)
date <- as.Date(c('1950-11-1','2028-3-25','1940-3-14'))
location <- c("Paris", "London", "Berlin")
df <- data.frame(date, location)
df$date_new <- ifelse(df$location %in% c("London"), df$date - years(100), df$date)

如您所见,我安装了 lubridate 包并尝试使用 if else 语句,但这只会在新列中给出一些负数。

解决方案可能非常简单,但我想不出来,快把我逼疯了。

谢谢!

试试这个作为替代方案

df$date_new <- df$date
df$date_new[df$location=="London"] <- df$date_new[df$location=="London"] - years(100)

或代替df$date_new <- ifelse(df$location %in% c("London"), df$date - years(100), df$date)

尝试

df$date_new <- ifelse(df$location %in% c("London"), as.character(df$date - years(100)), as.character(df$date))

ifelse 正在从测试中获取 class 属性:

The mode of the result may depend on the value of test (see the examples), and the class attribute (see oldClass) of the result is taken from test and may be inappropriate for the values selected from yes and no.

Sometimes it is better to use a construction such as

(tmp <- yes; tmp[!test] <- no[!test]; tmp) , possibly extended to handle missing values in test.

所以看来最好不要用ifelse。这是一种解决方案:

> df$date_new = df$date
> df[location == "London",]$date_new = df[location == "London",]$date_new - years(100)
> df
        date location   date_new
1 1950-11-01    Paris 1950-11-01
2 2028-03-25   London 1928-03-25
3 1940-03-14   Berlin 1940-03-14

但是,如果你想使用 ifelse,如果指定标准原点(R 中的对象),你可以将对象强制转换为 Date

> library(lubridate)
> date <- as.Date(c('1950-11-1','2028-3-25','1940-3-14'))
> location <- c("Paris", "London", "Berlin")
> df <- data.frame(date, location)
> df$date_new <- as.Date(ifelse(df$location == "London", as.Date(df$date - years(100)), df$date), origin = origin)
> df
        date location   date_new
1 1950-11-01    Paris 1950-11-01
2 2028-03-25   London 1928-03-25
3 1940-03-14   Berlin 1940-03-14