【问题标题】:R strip split a column in dataframeR条分割数据框中的一列
【发布时间】:2017-02-09 22:13:30
【问题描述】:

我有一个“数据”框架,有多个列,其中之一是“运行时”,它有两种格式的数据:

Runtime
1 h 10 min
67 min
1 h 0 min
86 min
97 min

我想将它们全部转换为分钟。尝试过“strsplit”和“strip_split_fixed”。谁能告诉我实现目标的方法、拆分或任何其他方法?

提前谢谢你!

【问题讨论】:

  • 当前是字符串吗?还是一个因素?
  • 这不是 R 输出。您能为您的示例提供实际的 R 代码吗?这样可以避免“哦,您的解决方案适用于我的示例,但不适用于我的实际数据”

标签: r regex string split


【解决方案1】:

我想我在某处看到过这种解决方案。别打我。

df = data.frame(Runtime = c('1 h 10 min', '67 min', '1 h 0 min', '86 min', '97 min'))

df$exp <- gsub("h", "* 60 +", df$Runtime)
df$exp <- gsub("min", "* 1", df$exp)

sapply(df$exp, FUN = function(x) eval(parse(text = x)))

1 * 60 + 10 * 1          67 * 1  1 * 60 + 0 * 1          86 * 1          97 * 1 
             70              67              60              86              97 

【讨论】:

    【解决方案2】:

    您可以使用gsubfn 和正则表达式一通电话:

    library(gsubfn)
    gsubfn("^(?:(\\d+)\\s*h)?\\s*(\\d+)\\s*min.*$",
     ~ sum(as.numeric(x) * 60, as.numeric(y), as.numeric(z), na.rm=TRUE), x)
    #[1] "70" "67" "60" "86" "97"
    

    【讨论】:

    • 谢谢皮埃尔。这真是令人印象深刻。试图在另一个问题中实现您的方法,但卡住了。我有类似的问题,我有类似的财务价值;预算:2.00E+07、7.50E+07、500000、3.05E+07。不知道我应该如何修改您的公式以在 10 内获得所有财务数据
    • 使用options(scipen=15)。然后再试一次
    • 太棒了!谢谢。如果不是像你这样知识的海洋,像我们这样的池塘早就干涸了
    • 乐于助人。别再看自然纪录片了
    【解决方案3】:

    下面是一个例子:

    # setting up your data.frame of interest
    df = data.frame(Runtime = c('1 h 10 min', '67 min', '1 h 0 min', '86 min', '97 min'))
    
    
    
    df$Runtime = gsub(' min', '', df$Runtime) # remove the min labels
    hrs = grepl('h', x = df$Runtime) # which values are in an "x h y min" format?
    runtime_sub = sapply(strsplit(df[hrs, 'Runtime'], ' h '), function(i) sum(as.numeric(i) * c(60, 1))) # convert the "x h y min" entries into numeric values in minutes
    df$Runtime = as.numeric(df$Runtime) # convert the vector to numeric (yes, it's supposed to return a warning. Ignore it.
    df[hrs, 'Runtime'] = runtime_sub # add the converted values
    

    这会导致:

      Runtime
    1      70
    2      67
    3      60
    4      86
    5      97
    

    【讨论】:

    • 绝对的天才!!非常感谢 CephBirk
    • 卡什没问题。无论您认为哪个答案最有帮助,您都可以投票和/或用绿色复选标记标记。这可以让每个人都知道您认为最有帮助的内容。
    【解决方案4】:

    1) 阅读df[[1]],如果第三列为NA,则第一列为分钟;否则,第一列加上第三列的 60 倍得出分钟数:

    with(read.table(text = as.character(df[[1]]), fill = TRUE), 
            ifelse(is.na(V3), V1, 60*V1 + V3))
    ## [1] 70 67 60 86 97
    

    2) 一种变体是在每个没有 h 的组件的开头粘贴“0 h”,给出 hm 并读取计算 60 倍第一列加上第三列.

    hm <- paste(ifelse(grepl("h", df[[1]]), "", "0 h"), df[[1]])
    with(read.table(text = hm), 60 * V1 + V3)
    ## [1] 70 67 60 86 97
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-15
      • 1970-01-01
      • 2021-09-11
      • 1970-01-01
      • 2021-08-23
      • 1970-01-01
      相关资源
      最近更新 更多