繁体   English   中英

显示每一列的唯一值

[英]show unique values for each column

我试图为每个列创建一个列类型和唯一变量的数据框。

我能够使用map(df, class) %>% bind_rows() %>% gather(key = col_name, value = col_class)以所需的数据帧格式获取列类型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)上相同的方法时map(df, unique)出现以下错误: Error: Argument 2 must be length 3, not 2预期的Error: Argument 2 must be length 3, not 2 ,但我不是确定如何解决它。

在这两列中,唯一值的数量不同。 您需要将它们简化为单个元素。

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   

我们可以使用map_df并将每一列中的classunique值合并为一个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在基数R中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)))))

为了解决OP的评论询问enframeunnest我成立了一个标杆。

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()快一点。

这对您有用吗?

data.table::rbindlist(list(map(df, class), map(df, function(x) list(unique(x)))))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM