वैक्टर से युक्त डेटाफ्रेम कॉलम को फ़िल्टर करें
मैं सेल की संपूर्ण सामग्री पर वैक्टर वाले कॉलम को फ़िल्टर करना चाहता हूं। मैंने R dplyr को देखा है । डेटाफ़्रेम को फ़िल्टर करें जिसमें संख्यात्मक वैक्टर का एक कॉलम होता है , लेकिन मेरी ज़रूरत थोड़ी अलग है।
नमूना df (नीचे पूर्ण विवरण)
df <- tibble::tribble(
~id, ~len, ~vec,
1L, 1L, 1L,
2L, 2L, 1:2,
3L, 2L, c(1L, 2L),
4L, 3L, c(1L, 2L, 3L),
5L, 3L, 1:3,
6L, 3L, c(1L, 3L, 2L),
7L, 3L, c(3L, 2L, 1L),
8L, 3L, c(1L, 3L, 2L),
9L, 4L, c(1L, 2L, 4L, 3L),
10L, 3L, c(3L, 2L, 1L)
)
देता है (मैचों के लिए रंग-कोडित)
मैं vec कॉलम को group_by कर सकता हूं :
dfg <- df %>%
group_by(vec) %>%
summarise(n = n()
,total_len = sum(len))
व्यक्तिगत कोशिकाओं के लिए, एक सीधी तुलना काम नहीं करती है, लेकिन समान है:
df$vec[4] == df$vec[5]
#> Error in df$vec[4] == df$vec[5]: comparison of these types is not implemented
identical(df$vec[4], df$vec[5])
#> [1] TRUE
लेकिन समकक्षों में से कोई भी एक फिल्टर में काम नहीं करता है, जो मुझे चाहिए:
df %>% filter(vec == c(1L, 2L, 3L))
#> Warning in vec == c(1L, 2L, 3L): longer object length is not a multiple of
#> shorter object length
#> Error: Problem with `filter()` input `..1`.
#> x 'list' object cannot be coerced to type 'integer'
#> i Input `..1` is `vec == c(1L, 2L, 3L)`.
df %>% filter(identical(vec, c(1L, 2L, 3L)))
#> # A tibble: 0 x 3
#> # ... with 3 variables: id <int>, len <int>, vec <list>
df %>% filter(identical(vec, vec[5]))
#> # A tibble: 0 x 3
#> # ... with 3 variables: id <int>, len <int>, vec <list>
मुझे यकीन है कि एक साधारण समाधान है जो मुझे याद आ रहा है।
एक और अधिक उन्नत आवश्यकता है जहां किसी भी क्रम में सेल की सामग्री का मिलान किया जाए, इसलिए ऊपर दिए गए 6 नारंगी, बैंगनी और स्वर्ण सभी मिलान करेंगे। एक समाधान जो सूचियों के साथ-साथ वैक्टर के साथ भी काम करता है वह भी बहुत अच्छा होगा क्योंकि यह भविष्य की आवश्यकता हो सकती है।
पूर्ण प्रतिनिधि:
library(tibble)
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
df <- tibble::tribble(
~id, ~len, ~vec,
1L, 1L, 1L,
2L, 2L, 1:2,
3L, 2L, c(1L, 2L),
4L, 3L, c(1L, 2L, 3L),
5L, 3L, 1:3,
6L, 3L, c(1L, 3L, 2L),
7L, 3L, c(3L, 2L, 1L),
8L, 3L, c(1L, 3L, 2L),
9L, 4L, c(1L, 2L, 4L, 3L),
10L, 3L, c(3L, 2L, 1L)
)
df
#> # A tibble: 10 x 3
#> id len vec
#> <int> <int> <list>
#> 1 1 1 <int [1]>
#> 2 2 2 <int [2]>
#> 3 3 2 <int [2]>
#> 4 4 3 <int [3]>
#> 5 5 3 <int [3]>
#> 6 6 3 <int [3]>
#> 7 7 3 <int [3]>
#> 8 8 3 <int [3]>
#> 9 9 4 <int [4]>
#> 10 10 3 <int [3]>
dfg <- df %>%
group_by(vec) %>%
summarise(n = n()
,total_len = sum(len))
#> `summarise()` ungrouping output (override with `.groups` argument)
dfg
#> # A tibble: 6 x 3
#> vec n total_len
#> <list> <int> <int>
#> 1 <int [1]> 1 1
#> 2 <int [2]> 2 4
#> 3 <int [3]> 2 6
#> 4 <int [3]> 2 6
#> 5 <int [3]> 2 6
#> 6 <int [4]> 1 4
df$vec[4] == df$vec[5]
#> Error in df$vec[4] == df$vec[5]: comparison of these types is not implemented
identical(df$vec[4], df$vec[5])
#> [1] TRUE
df %>% filter(vec == c(1L, 2L, 3L))
#> Warning in vec == c(1L, 2L, 3L): longer object length is not a multiple of
#> shorter object length
#> Error: Problem with `filter()` input `..1`.
#> x 'list' object cannot be coerced to type 'integer'
#> i Input `..1` is `vec == c(1L, 2L, 3L)`.
df %>% filter(identical(vec, c(1L, 2L, 3L)))
#> # A tibble: 0 x 3
#> # ... with 3 variables: id <int>, len <int>, vec <list>
df %>% filter(identical(vec, vec[5]))
#> # A tibble: 0 x 3
#> # ... with 3 variables: id <int>, len <int>, vec <list>
Created on 2021-01-13 by the reprex package (v0.3.0)
जवाब
चेतावनी से बचने के लिए तुलना करने के लिए थ्रो rowwise
और length
वेक्टर की जांच भी करें ।
library(dplyr)
compare <- c(1L, 2L, 3L)
df %>%
rowwise() %>%
filter(length(vec) == length(compare) && all(vec == compare))
# id len vec
# <int> <int> <list>
#1 4 3 <int [3]>
#2 5 3 <int [3]>
हम filter
पहले लंबाई तक कर सकते हैं जो बड़े डेटासेट पर अधिक तेज़ हो सकता है।
df %>%
filter(lengths(vec) == length(compare)) %>%
rowwise() %>%
filter(all(vec == compare))
आधार R में समान तर्क:
subset(df, sapply(vec, function(x)
length(x) == length(compare) && all(x == compare)))
हम इसका उपयोग कर सकते हैं map
library(dplyr)
library(purrr)
compare <- c(1L, 2L, 3L)
df %>%
filter(map_lgl(vec, ~ length(.x) == length(compare) && all(.x == compare)))
# A tibble: 2 x 3
# id len vec
# <int> <int> <list>
#1 4 3 <int [3]>
#2 5 3 <int [3]>