【问题标题】:string manipulation using ifelse within a for loop在 for 循环中使用 ifelse 进行字符串操作
【发布时间】:2014-07-30 13:13:04
【问题描述】:

我正在尝试解决一个起初看起来很简单但我发现自己陷入困境的问题。 所以,我有一个名为“out”的角色对象:

out<-c( " 59mn 59s", " 59mn 59s", " 1h 0mn",  " 1h 0mn",  " 1h 0mn",  " 1h 0mn",  " 1h 0mn", " 1h 0mn",   " 59mn 59s"," 59mn 59s", " 46mn 42s")

我的最终目标是使用 lubridate 包中的函数“hms”将角色转换为时间对象。问题是数据集并不一致,在某些情况下我有几小时和几分钟,而在其他情况下我有几分钟和几秒钟。所以我尝试这样统一数据集:

    out<-for(p in 1:length(out)) {                                         
 ifelse(!grepl("h",out[p]),paste("0h",out[p]),ifelse(!grepl("mn",out[p]),paste("0h 0mn",out[p]),ifelse(!grepl("s",out[p]),paste(out[p],"0s"))))                                                
                           } 

ifelse 语句本身可以正常工作,但是在 for 循环中它只返回 NULL。 有谁知道这段代码出了什么问题? 另一种选择是结合 lubridate 中的“hm”和“hms”功能,但我的技能不允许我走这条路。

非常感谢

【问题讨论】:

  • 初学者有一个很好的答案,但是如果您不保存 for 循环的结果而是打印每次迭代,您会看到发生了什么
  • 如果你想统一你的数据,你可能想删除一些字符串中的前导空格或最后一个空格。 (stackoverflow.com/q/10502787/2886003 可能会有所帮助)

标签: r if-statement for-loop lubridate


【解决方案1】:

由于ifelse 是矢量化的,因此您无需使用循环即可:

ifelse(!grepl("h",out), paste("0h",out),
       ifelse(!grepl("mn",out), paste("0h 0mn",out),
              ifelse(!grepl("s",out), paste(out,"0s"), NA)))

#[1] "0h  59mn 59s" "0h  59mn 59s" " 1h 0mn 0s"   " 1h 0mn 0s"   " 1h 0mn 0s"   " 1h 0mn 0s"   " 1h 0mn 0s"  
#[8] " 1h 0mn 0s"   "0h  59mn 59s" "0h  59mn 59s" "0h  46mn 42s"

这是你的预期吗?

(请注意,我添加了一个NA,以防所有其他条件都不为真,并将ifelse 中的out[p] 替换为仅out。)

【讨论】:

  • 我很确定第二行实际上是多余的。
  • 这是某种记录,帖子在不到 10 分钟内就得到了答复,而且效果很好。非常感谢您的帮助
  • @shadow,你可能是对的,其实我并没有花太多时间检查操作的逻辑。
  • @PatraoPedro 如果它完美运行并回答了您的问题,请随时接受答案:)
【解决方案2】:

使用一些更安全的正则表达式。

t<-c( " 59mn 59s", " 59mn 59s", " 1h 0mn",  " 1h 0mn",  " 1h 0mn",  " 1h 0mn",  " 1h 0mn", " 1h 0mn",   " 59mn 59s"," 59mn 59s", " 46mn 42s")
t[grep(" [0-9]{2}mn", t)] = paste( "0h", t[grep(" [0-9]{2}mn", t)], sep="")
t[grep("mn$", t)] = paste(t[grep("mn$", t)], " 0s", sep ="")

hms(t)
> [1] "59M 59S"  "59M 59S"  "1H 0M 0S" "1H 0M 0S" "1H 0M 0S" "1H 0M 0S" "1H 0M 0S"
> [8] "1H 0M 0S" "59M 59S"  "59M 59S"  "46M 42S" 

【讨论】:

  • 它确实增加了小时数。您正在查看 hms(t) 而不是 t
  • 没错,哈哈。我一直在学习 perl 的荒谬正则表达式,所以我喜欢使用任何正则表达式的答案。 +1
猜你喜欢
  • 2020-08-05
  • 1970-01-01
  • 2019-03-14
  • 2010-09-20
  • 2021-06-09
  • 1970-01-01
  • 1970-01-01
  • 2017-10-09
  • 1970-01-01
相关资源
最近更新 更多