【问题标题】:R: Quick Way to Select cells of a dataframe based on their lengthR:根据长度选择数据框单元格的快速方法
【发布时间】:2018-10-12 15:19:04
【问题描述】:

我有一个大数据框,我想根据字符串的长度对数据框进行子集化。

我对每一行都有字符限制和优先顺序。

例如:

Column1   Column2                Column3             Column4
A1    Hotels in London, UK   Hotels in London        Hotels

如果 len(column2)

即我的偏好是 column2 > column3 > column 4,但这些都受 30 个字符的限制。

目前,我有一个循环需要

 for(i in 1:nrow(df) {
  if(nchar(df$`C2`[i]) <= 30) {
    df[i]$`selected` <- df`C2`[i]
  } else if(nchar(df$`C3`[i]) <= 30) {
    df$`selected`[i] <- df$`C3`[i]
  } else (nchar(df$`C4[i]) <= 30) {
     df$`selected`[i]<- df$`C4`[i]

【问题讨论】:

    标签: r loops filter subset


    【解决方案1】:

    这应该可行:

    DF$Selected <- sapply(seq_len(nrow(DF)),
                          function(i) DF[i,which(nchar(DF[i,-1]) <= 30)[1] + 1] )
    

    简要说明

    对于每一行索引i 我们:

    • 选择行i(不包括第一列)的列值,我们存储它们的nchar
      nchar(DF[i,-1])
    • 取先前计算的“nchars”的第一个索引,即&lt;= 30
      which(nchar(DF[i,-1]) &lt;= 30)[1]
    • 然后我们使用这个索引来选择列(我们需要给这个索引加上+1,因为我们没有考虑第一列)
    • 1:nrow(DF)* 中的每个i 使用sapply 之前的操作,并返回一个向量,我们将其存储到DF 的新列中,称为Select

    (*)

    seq_len(nrow(DF)) 在逻辑上等同于1:nrow(DF),但更安全,因为如果DF 没有行,它将返回一个空向量,而1:nrow(DF) 将返回c(1,0)(通常会产生“奇怪”的结果)

    【讨论】:

      【解决方案2】:

      您可以在dplyr 中使用case_when 对某个列进行条件选择。它是矢量化的,所以应该比循环更快。

      library(dplyr)
      df %>% mutate(selected = case_when(nchar(Column2)<30 ~ Column2,
                                     nchar(Column2)>30 & nchar(Column3)<30 ~ Column3,
                                     nchar(Column2)>30 & nchar(Column3)>30 ~ Column4
                                     ))
      

      【讨论】:

        猜你喜欢
        • 2016-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-28
        相关资源
        最近更新 更多