【问题标题】:Use dplyr to filter out columns containing characters使用 dplyr 过滤掉包含字符的列
【发布时间】:2014-12-04 08:32:27
【问题描述】:

我有一个大型数据框,我想使用我最近发现的优秀包dplyr (Wickham)。我想过滤掉包含字符的列。这可能吗?

例如,在nycflights13 包内的flights 数据集中,如何过滤掉具有character 类的列?

library(nycflights13)
data(flights)
str(flights)
Classes ‘tbl_df’, ‘tbl’ and 'data.frame':   336776 obs. of  16 variables:
 $ year     : int  2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
 $ month    : int  1 1 1 1 1 1 1 1 1 1 ...
 $ day      : int  1 1 1 1 1 1 1 1 1 1 ...
 $ dep_time : int  517 533 542 544 554 554 555 557 557 558 ...
 $ dep_delay: num  2 4 2 -1 -6 -4 -5 -3 -3 -2 ...
 $ arr_time : int  830 850 923 1004 812 740 913 709 838 753 ...
 $ arr_delay: num  11 20 33 -18 -25 12 19 -14 -8 8 ...
 $ carrier  : chr  "UA" "UA" "AA" "B6" ...
 $ tailnum  : chr  "N14228" "N24211" "N619AA" "N804JB" ...
 $ flight   : int  1545 1714 1141 725 461 1696 507 5708 79 301 ...
 $ origin   : chr  "EWR" "LGA" "JFK" "JFK" ...
 $ dest     : chr  "IAH" "IAH" "MIA" "BQN" ...
 $ air_time : num  227 227 160 183 116 150 158 53 140 138 ...
 $ distance : num  1400 1416 1089 1576 762 ...
 $ hour     : num  5 5 5 5 5 5 5 5 5 5 ...
 $ minute   : num  17 33 42 44 54 54 55 57 57 58 ...

有什么想法吗?

【问题讨论】:

  • 这有点迂腐,但仅供参考,在 dplyr 中,您使用 select 选择列,使用 filter 选择行 - 所以从技术上讲,您不能“过滤列”。
  • 我的回答是“为什么?”。您想对需要删除所有字符列的这个(或其他一些)数据集做什么?可能有更好的方法...
  • 有。在我的回答中,使用Filter
  • @RichardScriven 那是如何,我在问为什么。我能想到去掉 char 列的唯一原因是转换为数字矩阵,但这里的数字列是如此不同,我想不出为什么要这样做......

标签: r dplyr


【解决方案1】:

你可以试试 summarise_each 从dplyr

library(dplyr) 
indx <- which(unlist(summarise_each(flights, funs(class))!='character'))
flights %>% 
       select(indx)

【讨论】:

  • 我猜summarise_each 比colwise 容易。没有意识到它可以解决问题。
  • @RichardScriven 我用flights 进行了测试。似乎运作良好。
  • 你准备好迎接这个了吗..select(flights, summarise_each(flights, funs(is.character(.))) %&gt;% unlist() %&gt;% which())哈哈。 dplyr 挺好玩的
  • @RichardScriven 最初,我使用与is.character 略有不同的一个。
【解决方案2】:

你不需要dplyr,你可以使用base R:

flights[, !sapply(flights, is.character)]

【讨论】:

    【解决方案3】:

    我认为没有dplyr 的快捷方式,但你可以得到你想要的:

    flights %>% select(which(sapply(flights, class) != 'character'))
    
    # Source: local data frame [336,776 x 12]
    # 
    #    year month day dep_time dep_delay arr_time arr_delay flight air_time distance hour minute
    # 1  2013     1   1      517         2      830        11   1545      227     1400    5     17
    # 2  2013     1   1      533         4      850        20   1714      227     1416    5     33
    # 3  2013     1   1      542         2      923        33   1141      160     1089    5     42
    # 4  2013     1   1      544        -1     1004       -18    725      183     1576    5     44
    # 5  2013     1   1      554        -6      812       -25    461      116      762    5     54
    # 6  2013     1   1      554        -4      740        12   1696      150      719    5     54
    # 7  2013     1   1      555        -5      913        19    507      158     1065    5     55
    # 8  2013     1   1      557        -3      709       -14   5708       53      229    5     57
    # 9  2013     1   1      557        -3      838        -8     79      140      944    5     57
    # 10 2013     1   1      558        -2      753         8    301      138      733    5     58
    # ..  ...   ... ...      ...       ...      ...       ...    ...      ...      ...  ...    ...
    

    【讨论】:

    • 这个的变体是flights %&gt;% select(-which(sapply(flights, is.character)))
    • -which 是个坏主意。在没有字符列的 data.frame 上尝试。
    【解决方案4】:

    我没有航班数据,但这种方法也适用于我尝试过的其他一些数据

    do(flights, Filter(Negate(is.character), .))
    

    当然,总有基础 R。对于这项任务,它似乎更容易一些

    Filter(Negate(is.character), flights)
    

    【讨论】:

    • @beginneR - 谢谢,我删除了它。显然其他人也不同意
    • @beginneR - 我现在意识到我错误地使用了colwise。将逻辑向量替换为 select 及其名称和所有内容会更好,更容易,我正在做 .dots = names(vec)[vec]
    • 其实这样更好看f &lt;- Negate(is.character); select_(flights, names(numcolwise(f)(flights)))
    【解决方案5】:

    这是一个使用 select_if() 的 dplyr/tidyverse 选项(使用 dplyr starwars 示例数据):

    starwars %>% 
      select_if(~!is.character(.)) %>% 
      head(2)
    
    # A tibble: 2 x 6
        height  mass birth_year films     vehicles  starships
         <int> <dbl>      <dbl> <list>    <list>    <list>   
      1    172    77         19 <chr [5]> <chr [2]> <chr [2]>
      2    167    75        112 <chr [6]> <chr [0]> <chr [0]>
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-10
      • 1970-01-01
      • 2021-12-18
      • 2022-06-20
      • 2017-08-15
      • 1970-01-01
      • 2022-01-19
      • 2022-11-02
      相关资源
      最近更新 更多