Удалить столбцы из data.frame, которые имеют тип списка - PullRequest
0 голосов
/ 15 мая 2019

Учитывая data.frame, который имеет столбцы списка и пытается записать его в CSV-файл, как пользователь может удалить все столбцы типа list?

dput будет довольно длинным. Смотрите пример здесь Обратите внимание, что full 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 ]

3 голосов
/ 15 мая 2019

Учитывая

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(...)
}
2 голосов
/ 15 мая 2019

Если вам нужно использовать логическое индексирование:

  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, мы можем использовать keep и negate:

keep(dat, negate(is.list))

В противном случае:

Мы можем удалить:

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