我在 RStudio 中使用一个包含日期的列的数据框。有些行包含年份,例如 1687,其他行包含日期格式,例如 12/12/23,还有一些包含字符,例如“19 世纪上半叶”。我正在尝试从此列中提取数值。
我从所有行中提取数值的方式期望包含“/”的行,因为我想保持原样。这是我的代码:
detect<-str_detect("/", MR_all$period)
MR_all$period[detect=FALSE]
MR_all['period_3']=dplyr::case_when(MR_all$period[detect=FALSE]~gsub("\\D", "",MR_all$period))
这不起作用,因为检测功能无法检测斜线并打印所有观察结果。非常感谢您帮助编写检测“/”
的函数您正在使用单个
=
进行比较,如 [detect=FALSE]
,它将返回 nothing,c.f.,mtcars$cyl[detect=FALSE]
(有或没有 detect
先前分配,这不会检查或使用如果它存在的话)。
为什么?因为单个
=
是一个 assignment,所以在这种情况下,您正在创建(在本例中,覆盖)一个名为 detect
的具有单个值 FALSE
的对象。因为赋值无形地将分配的值返回给调用部分,这意味着它周围的[..]
被传递了一个单一的FALSE
。实际上,MR_all$period[FALSE]
是你告诉 R 你想做的事情,它很乐意返回一个长度为 0 的向量(可能是 character(0)
,但我猜……见 #2)。
由于您使用的是
str_detect("/", MR_all$period)
,这表明 MR_all$period
是 strings(character
类)的列,因此您下一次使用 MR_all$period[detect==FALSE] ~ gsub(..)
似乎是错误的:的左侧 (LHS) ~
中的 case_when
对必须按逻辑解析,所以 a_string ~ gsub(..)
是错误的。
此外,即使
MR_all$period[detect==FALSE]
确实解决了一些合乎逻辑的问题,以便 case_when
将继续,我们也会遇到这个向量比原始帧中的行数短的问题,但你正在重新分配这个较短的 -矢量回到整个MR_all['period_3']
,如果你幸运会警告或失败,但如果你不是那么它会默默地将数据回收到你的框架中(这是一个逻辑问题,也是我的主要抱怨关于回收参数)。
最终,我认为您需要以下之一:
只为
gsub
为真的那些行分配period
ed版本的detect
,为所有其他行返回NA
:
MR_all['period_3'] <- dplyr::case_when(
detect == FALSE ~ gsub("\\D", "", MR_all$period)
)
同上,但如果不正确则默认为
period
MR_all['period_3'] <- dplyr::case_when(
detect == FALSE ~ gsub("\\D", "", MR_all$period),
TRUE ~ MR_all$period
)
或者dplyr-1.1.0中的首选方法:
MR_all['period_3'] <- dplyr::case_when(
detect == FALSE ~ gsub("\\D", "", MR_all$period),
.default = MR_all$period
)