वेक्टर के रूप में एक dplyr tbl कॉलम निकालें


175

क्या डेटाबेस के बैक-एंड (यानी डेटा फ़्रेम / टेबल को सीधे सब्मिट नहीं किया जा सकता है) के साथ tbl से सदिश tbl के एक कॉलम को वेक्टर के रूप में प्राप्त करने का एक अधिक सफल तरीका है?

require(dplyr)
db <- src_sqlite(tempfile(), create = TRUE)
iris2 <- copy_to(db, iris)
iris2$Species
# NULL

यह बहुत आसान होता, इसलिए

collect(select(iris2, Species))[, 1]
# [1] "setosa"     "setosa"     "setosa"     "setosa"  etc.

लेकिन यह थोड़ा अनाड़ी लगता है।


है collect(iris2)$Speciesकम अनाड़ी?
सीजे येटमैन

जवाबों:


178

डॉपलर 0.7.0 के साथ, आप pullसदिश से एक वेक्टर प्राप्त करने के लिए उपयोग कर सकते हैं tbl


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
db <- src_sqlite(tempfile(), create = TRUE)
iris2 <- copy_to(db, iris)
vec <- pull(iris2, Species)
head(vec)
#> [1] "setosa" "setosa" "setosa" "setosa" "setosa" "setosa"

96

@Nacnudus की टिप्पणी के अनुसार, ऐसा लगता है कि pullफ़ंक्शन को duspr 0.6 में लागू किया गया था:

iris2 %>% pull(Species)

Dplyr के पुराने संस्करणों के लिए, यहां कॉलम को थोड़ा अच्छे (टाइप करने के लिए आसान, और पढ़ने में आसान) बनाने के लिए एक साफ काम किया गया है:

pull <- function(x,y) {x[,if(is.name(substitute(y))) deparse(substitute(y)) else y, drop = FALSE][[1]]}

यह आपको इनमें से कोई भी करने देता है:

iris2 %>% pull('Species')
iris2 %>% pull(Species)
iris2 %>% pull(5)

जिसके परिणामस्वरूप...

 [1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 15.2 10.4 10.4 14.7 32.4 30.4 33.9 21.5 15.5 15.2 13.3 19.2 27.3 26.0 30.4 15.8 19.7 15.0 21.4

और यह डेटा फ्रेम के साथ भी ठीक काम करता है:

> mtcars %>% pull(5)
 [1] 3.90 3.90 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 3.92 3.07 3.07 3.07 2.93 3.00 3.23 4.08 4.93 4.22 3.70 2.76 3.15 3.73 3.08 4.08 4.43
[28] 3.77 4.22 3.62 3.54 4.11

इसका एक अच्छा तरीका v0.2 में है dplyr:

iris2 %>% select(Species) %>% collect %>% .[[5]]

या यदि आप पसंद करते हैं:

iris2 %>% select(Species) %>% collect %>% .[["Species"]]

या अगर आपकी तालिका बहुत बड़ी नहीं है, तो बस ...

iris2 %>% collect %>% .[["Species"]]

2
मुझे आपका पुल फंक्शन पसंद है। मैं सिर्फ उन मामलों के लिए एक सरलीकरण pull <- function(x, y) { if (ncol(x) == 1) y <- 1 else y x[ , if (is.name(substitute(y))) deparse(substitute(y)) else y, drop = FALSE][[1]] }iris2 %>% pull()
जोड़ूंगा

7
आप डेटा फ़्रेम से वेक्टर खींचने के लिए magrittrएक्सपोज़र ऑपरेटर ( %$%) का भी उपयोग कर सकते हैं । यानी iris2 %>% select(Species) %>% collect() %$% Species
सीसमिथ

@ ल्यूक1018 को आपको इस टिप्पणी से उत्तर देना चाहिए
rrs

pull()dplyr संस्करण 0.6 github.com/tidyverse/dplyr/commit/… पर
nacnudus

72

आप इसका उपयोग भी कर सकते हैं, unlistजिसे मुझे पढ़ना आसान लगता है क्योंकि आपको कॉलम का नाम दोहराने या सूचकांक को निर्दिष्ट करने की आवश्यकता नहीं है।

iris2 %>% select(Species) %>% unlist(use.names = FALSE)

1
यह सबसे बहुमुखी तरीका लगता है क्योंकि यह वैक्टर और डेटा.फ्रेम के साथ पहचान से काम करता है, अर्थात यह कार्यों को अधिक अज्ञेय बनाता है।
जिओटॉरी

मैं बस इस सटीक प्रश्न का उत्तर ढूंढ रहा था और unlistठीक वही है जिसकी मुझे आवश्यकता थी। धन्यवाद!
एंड्रयू ब्रूजा

unlistकई स्तंभों से मान निकाल सकते हैं (सभी मानों को एक एकल वेक्टर में जोड़ते हुए), जबकि dplyr::pullएक एकल स्तंभ तक सीमित है।
फाइलअप

21

मैं से extract2सुविधा समारोह का उपयोग करेगा magrittr:

library(magrittr)
library(dplyr)

iris2 %>%
  select(Species) %>%
  extract2(1)  

क्या आप के collect()बीच selectऔर उपयोग करने का मतलब था extract2?
9

10
use_series(Species)शायद और भी पठनीय है। इन कार्यों के लिए मुझे सचेत करने के लिए धन्यवाद, ऐसे कई अन्य काम हैं जहाँ से आया था।
nacnudus

20

मैं शायद लिखूंगा:

collect(select(iris2, Species))[[1]]

चूंकि dplyr को डेटा के tbls के साथ काम करने के लिए डिज़ाइन किया गया है, इसलिए डेटा का एक भी कॉलम प्राप्त करने का कोई बेहतर तरीका नहीं है।


इससे अधिक उचित नहीं कह सकते। यह सांत्वना में अंतःक्रियात्मक रूप से उत्पन्न हुआ जब मैंने सहज मूल्यों के लिए जाँच करने के लिए अद्वितीय (तालिका $ स्तंभ) का उपयोग करने का प्रयास किया।
nacnudus

4
उस मामले के लिए @nacnudus आप भी कर सकते हैंgroup_by(column) %.% tally()
हैडली

12
एक तर्क drop = TRUEके लिए dplyr::selectकाफी कई उपयोग के मामलों में जहाँ हम वास्तव में वैक्टर को निकालने के लिए की जरूरत के लिए अद्भुत होगा।
एंटोनी लिज़ी

यह एकमात्र तरीका था जिससे मैं अपने Sparklyr sdf से एक कॉलम प्राप्त कर सकता था। पुल 0.7.8 संस्करण पर मेरे लिए काम नहीं कर रहा था।
मेप

16

@ ल्यूक1018 ने इस समाधान को एक टिप्पणी में प्रस्तावित किया:

आप डेटा फ़्रेम से वेक्टर खींचने के लिए magrittrएक्सपोज़र ऑपरेटर ( %$%) का भी उपयोग कर सकते हैं ।

उदाहरण के लिए:

iris2 %>% select(Species) %>% collect() %$% Species

मैंने सोचा कि यह अपने ही जवाब के लायक है।


मुझे इसकी तलाश थी।
डिएगो-एमएक्स

अगर मैं स्वयं कॉलनाम नहीं बल्कि एक स्ट्रिंग वैरिएबल पास करना चाहता हूं तो मैं इसे कैसे करूंगा?
mzuba

@mzuba tibble(x = 1:10, y = letters[1:10]) %>% select_("x") %>% unlist()और %>% unname()यदि आप चाहें तो आप अंत में एक और जोड़ सकते हैं, लेकिन मेरे उद्देश्यों के लिए मुझे आवश्यक नहीं है कि अंतिम पाइप श्रृंखला कड़ी मिल गई है। आप कमांड use.names = FALSEमें भी निर्दिष्ट कर सकते हैं unlist(), जो unname()पाइप श्रृंखला पर जोड़ने के समान कार्य करता है ।
मार्क व्हाइट

1
@mzuba मैं pullअब कमांड का उपयोग करूंगा । मेरा समाधान dplyrसंस्करण 0.6 से पहले लिखा गया था ।
आरआरएस

1
ध्यान दें कि %$%किसी भी सूची में काम करता है, जबकि pull()नहीं है
wint3rschlaefer

2

यदि आप अनुक्रमण के लिए वर्गाकार कोष्ठक का उपयोग करने के लिए उपयोग किए जाते हैं, तो एक अन्य विकल्प केवल सामान्य अनुक्रमण दृष्टिकोण को डिफ्रेम () , जैसे:

library(tidyverse)

iris2 <- as_tibble(iris)

# using column name
deframe(iris2[, 'Sepal.Length'])

# [1] 5.1 4.9 4.7 4.6 5.0 5.4

# using column number
deframe(iris2[, 1])

# [1] 5.1 4.9 4.7 4.6 5.0 5.4

वह और पुल () दोनों एक अच्छा स्तंभ होने के बहुत अच्छे तरीके हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.