我正在尝试创建一个具有列类型和每个列唯一变量的数据框。
我可以使用map(df, class) %>% bind_rows() %>% gather(key = col_name, value = col_class)
以所需的数据框架格式获取列类型,但是无法获取唯一变量以使其成为数据框架而不是列表。
下面是一个小的数据框和代码,它们在列表中获得唯一变量,但不在数据框中。理想情况下,我可以在一个(地图)函数中执行此操作,但是如果我必须加入它们,那没什么大不了的。
df <- data.frame(v1 = c(1,2,3,2), v2 = c("a","a","b","b"))
library(tidyverse)
map(df, class) %>% bind_rows() %>% gather(key = col_name, value = col_class)
map(df, unique)
当我尝试在map(df, unique)
上使用与map(df, class)
相同的方法时,出现以下错误:Error: Argument 2 must be length 3, not 2
,这是预期的,但我不确定如何解决它。
答案 0 :(得分:1)
这两列中唯一值的数量不同。您需要将它们简化为单个元素。
df2 <- map(df, ~str_c(unique(.x),collapse = ",")) %>%
bind_rows() %>%
gather(key = col_name, value = col_unique)
> df2
# A tibble: 2 x 2
col_name col_class
<chr> <chr>
1 v1 1,2,3
2 v2 a,b
答案 1 :(得分:1)
我们可以使用map_df
并将每一列中的class
和unique
值分成一个tibble
。由于每一列将具有不同类型的变量,因此我们需要将它们放在一个公共类中,以将数据绑定到一个数据帧中。
purrr::map_df(df,~tibble::tibble(class = class(.), value = as.character(unique(.))))
# class value
# <chr> <chr>
#1 numeric 1
#2 numeric 2
#3 numeric 3
#4 factor a
#5 factor b
或者如果您希望每一列只有一个值,我们可以这样做
map_df(df, ~tibble(class = class(.), value = toString(unique(.))))
# class value
# <chr> <chr>
#1 numeric 1, 2, 3
#2 factor a, b
使用lapply
do.call(rbind, lapply(df, function(x)
data.frame(class = class(x), value = as.character(unique(x)))))
和
do.call(rbind, lapply(df, function(x)
data.frame(class = class(x), value = toString(unique(x)))))
答案 2 :(得分:1)
为了解决OP关于enframe
和unnest
的评论,我建立了一个基准。
set.seed(123)
df <- data.frame(v1 = sample(1:100000,10000000, replace = TRUE),
v2 = sample(c(letters,LETTERS),10000000, replace = TRUE))
library(tidyverse)
map(df, ~str_c(unique(.x),collapse = ",")) %>%
bind_rows() %>%
gather(key = col_name, value = col_unique)
#> # A tibble: 2 x 2
#> col_name col_unique
#> <chr> <chr>
#> 1 v1 51663,57870,2986,29925,95246,68293,62555,45404,65161,46435,9642~
#> 2 v2 S,V,k,t,z,K,f,J,n,R,W,h,M,P,q,g,C,U,a,d,Y,u,O,x,b,m,v,r,F,w,A,j~
map(df, ~str_c(unique(.x),collapse = ",")) %>%
enframe() %>%
unnest()
#> # A tibble: 2 x 2
#> name value
#> <chr> <chr>
#> 1 v1 51663,57870,2986,29925,95246,68293,62555,45404,65161,46435,9642,59~
#> 2 v2 S,V,k,t,z,K,f,J,n,R,W,h,M,P,q,g,C,U,a,d,Y,u,O,x,b,m,v,r,F,w,A,j,c,~
microbenchmark::microbenchmark(
bind_gather = map(df, ~str_c(unique(.x),collapse = ",")) %>%
bind_rows() %>%
gather(key = col_name, value = col_unique) ,
frame_unnest = map(df, ~str_c(unique(.x),collapse = ",")) %>%
enframe() %>%
unnest() ,
times = 10)
#> Unit: milliseconds
#> expr min lq mean median uq max neval
#> bind_gather 581.6403 594.6479 615.0841 612.9336 618.3057 697.6204 10
#> frame_unnest 568.6620 590.0003 604.2774 606.5676 624.8159 630.2372 10
似乎enframe %>% unnest
比使用bind_rows %>% gather()
快一点。
答案 3 :(得分:0)
这对您有用吗?
$('#app-container').on('click', '.js-dropdown, .js-dropdown-menu > *', function(event){
event.preventDefault();
var that = this;
var parent = $(this).closest('.is-parent');
//is our dropdown open?
if(!parent.hasClass('is-open')){
//... then open it.
parent.addClass('is-open');
//handle clicking away
$(document).one('click', function closeMenu(docEvent){
//if the parent does not contain the clicked element...
if($(parent).has(docEvent.target).length === 0) {
//close it.
parent.removeClass('is-open');
} else {
// else, set up another listener to check the next user click.
$(document).one('click', closeMenu);
}
});
} else {
// ...else we close it.
parent.removeClass('is-open');
}
event.stopPropagation();});