[英]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
并将每一列中的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
在基数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的评论询问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()
快一点。
这对您有用吗?
data.table::rbindlist(list(map(df, class), map(df, function(x) list(unique(x)))))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.