【问题标题】:How to preprocess a character column in an R data frame如何预处理 R 数据框中的字符列
【发布时间】:2018-02-13 21:02:04
【问题描述】:

给定这个数据框

row | time | name
-----------------
1   | 2 min| bob
2   | 7 min| john
3   | 1 hr 5 min| jess

我想将时间列处理为包含分钟数的数字列。我有一个函数可以将字符串处理成一个数字,但是当我尝试用apply 它来改变/转换原始数据帧data.frame(apply(dataframe, 2, parse_str)) 时,它会崩溃或根本不起作用。一旦我可以应用转换函数,我计划通过df = as.numeric(as.character(dataframe$time)) 将字符列转换为数字,但尚未测试。

关于如何让我的预处理函数正确地变异/转换/创建新数据帧有什么想法吗?

【问题讨论】:

  • dataframe$time2 <- parse_str(dataframe$time)? apply 用于对 all 列执行相同的操作,通常您不会在数据框的 all 上使用它,而只会在矩阵上使用它。
  • 您不太可能使用apply 函数。在寻求帮助时,您应该包含一个简单的reproducible example,其中包含示例输入和所需的输出,可用于测试和验证可能的解决方案。显示您尝试过的代码,我们可以帮助您修复它。
  • 另一种选择可能是将0 hr 附加到没有小时数的所有内容上,即将其正则表达式为^d+ hr,使用stringi,然后使用lubridate's hm() 以正确格式转换它们,即lubridate::hm(c('0 hr 2 min', '0 hr 7 min', '1 hr 5 min')) ..

标签: r dataframe apply lapply sapply


【解决方案1】:

正如 cmets 所说,最好不要使用apply

> df <- data.frame(time=c('2 min', '7 min', '1 hr 5 min'), name = c('bob', 'john', 'jess'))
> df
        time name
1      2 min  bob
2      7 min john
3 1 hr 5 min jess
> df$time <- as.numeric(parse_str(df$time))
> df
        time name
1          2  bob
2          7 john
3         65 jess

如果您的parse_str 函数如您所说返回数字,那么您甚至不需要as.numeric 调用。

【讨论】:

  • 太棒了,谢谢!花了几个小时不知道该怎么做哈哈,太简单了。
  • parse_str 作用于单个字符串,而不是列。当我尝试此代码时,它将每一行设置为第一行的结果 parse_str 。关于如何将其应用于每一行的任何想法?
  • 我建议让 parse_str 处理长度大于 1 的字符向量(最好将函数向量化)。如果您不想这样做,那么df$time &lt;- sapply(df$time, parse_str) 怎么样?
  • 谢谢!关于如何向量化函数的任何提示?我应该在函数内添加一个循环吗?这似乎是一种缓慢、不雅的方式。
  • This link 是一个很好的起点,底部有更多参考资料。基本上你可以只使用 R 内置的矢量化函数来进行矢量化,但如果你的逻辑太复杂,那就不值得努力了。
【解决方案2】:

这是另一个使用 的选项,适用于可能想要重现您的结果但没有您的功能的任何人。使用the date from C. Braun's answer

# install.packages(c("tidyverse", "lubridate"), dependencies = TRUE)
library(tidyverse)
library(lubridate)

df %>% mutate(
            `t formated` = str_replace(time, "(^[0-9] min)", "0 hr \\1"),
            `t hours minues` = hm(`t formated`),
            `t duration` = as.duration(`t hours minues`),
            `t numeric` = as.numeric(`t duration`, "minutes")
            ) %>% as_tibble()
#> # A tibble: 3 x 6
#>         time   name `t formated` `t hours minues`        `t duration` `t numeric`
#>       <fctr> <fctr>        <chr>     <S4: Period>      <S4: Duration>       <dbl>
#> 1      2 min    bob   0 hr 2 min            2M 0S   120s (~2 minutes)           2
#> 2      7 min   john   0 hr 7 min            7M 0S   420s (~7 minutes)           7
#> 3 1 hr 5 min   jess   1 hr 5 min         1H 5M 0S 3900s (~1.08 hours)          65

【讨论】:

    猜你喜欢
    • 2018-06-05
    • 1970-01-01
    • 2014-04-27
    • 1970-01-01
    • 1970-01-01
    • 2021-01-20
    • 1970-01-01
    • 1970-01-01
    • 2019-12-25
    相关资源
    最近更新 更多