从data.frame中删除列表类型的列

时间:2019-05-15 19:17:27

标签: r list dataframe subset

给出一个具有列表列的data.frame并尝试将其写入csv文件,用户如何删除所有类型为list的列?

dput将相当长。在这里查看示例 请注意,完整df具有5个以上的列表列,我更喜欢不枚举它们或按名称查找它们。

> str(df,max.level=1)
Classes ‘tbl_df’, ‘tbl’ and 'data.frame':   2237 obs. of  30 variables:
 $ CATEGORY    : chr  "ARTICLE " "ARTICLE " "ARTICLE " "ARTICLE " ...
 $ BIBTEXKEY   : chr  "RN69" "RN4023" "RN3332" "RN58" ...
 $ ADDRESS     : chr  NA NA NA NA ...
 $ ANNOTE      : chr  NA NA NA NA ...
 $ AUTHOR      :List of 2237
 $ BOOKTITLE   : chr  NA NA NA NA ...
 and 40+ other columns

> names(df)
 [1] "CATEGORY"     "BIBTEXKEY"    "ADDRESS"      "ANNOTE"       "AUTHOR"       "BOOKTITLE"   
 [7] "CHAPTER"      "CROSSREF"     "EDITION"      "EDITOR"       "HOWPUBLISHED" "INSTITUTION" 
[13] "JOURNAL"      "KEY"          "MONTH"        "NOTE"         "NUMBER"       "ORGANIZATION"
[19] "PAGES"        "PUBLISHER"    "SCHOOL"       "SERIES"       "TITLE"        "TYPE"        
[25] "VOLUME"       "YEAR"         "ISSN"         "DOI"          "ISBN"         "URL"         
> 

该命令应类似于

df %>% select_if(!is.list),但并不完全正确

df来自

devtools::install_github("ropensci/bib2df")
library(bib2df)
url <- "https://cprd.com/bibliography/export/bibtex"
df <- bib2df(url)

这样可以正确选择它们,但求反似乎很困难

df %>% select_if(is_list)

2 个答案:

答案 0 :(得分:3)

给予

dat <- tibble::tibble(a = 1,
                      b = list(d = c(1, 2)))

我们可以使用

Filter(Negate(is.list), dat)

获得

# A tibble: 1 x 1
#      a
#  <dbl>
#1     1

在控制台中输入Negate,我们将看到它的作用

function (f) 
{
    f <- match.fun(f)
    function(...) !f(...)
}

答案 1 :(得分:2)

如果您需要使用逻辑索引:

  df[,!purrr::map_lgl(df,is.list)] %>% 
   names()
 [1] "CATEGORY"     "BIBTEXKEY"    "ADDRESS"      "ANNOTE"       "BOOKTITLE"   
 [6] "CHAPTER"      "CROSSREF"     "EDITION"      "HOWPUBLISHED" "INSTITUTION" 
[11] "JOURNAL"      "KEY"          "MONTH"        "NOTE"         "NUMBER"      
[16] "ORGANIZATION" "PAGES"        "PUBLISHER"    "SCHOOL"       "SERIES"      
[21] "TITLE"        "TYPE"         "VOLUME"       "YEAR"         "ISSN"        
[26] "DOI"          "ISBN"         "URL"  

您也可以执行df %>% select_if(Negate(is.list))

此外,正如@akrun所述, 您可以简单地使用discard中的purrr

purrr::discard(dat, is.list) 

或者如@markus所指出的,我们可以使用keepnegate

keep(dat, negate(is.list))

否则:

我们可以嵌套:

library(tidyverse)
df %>% 
  unnest(AUTHOR) %>% 
  select(-AUTHOR)