dplyr সংক্ষিপ্তসার: আউটপুটে শূন্য দৈর্ঘ্যের দলগুলিকে রাখতে ".pd = FALSE" এর সমান


98

এর ফাংশন summariseসহ ব্যবহার করার সময় , খালি বিভাগগুলি ডিফল্টরূপে বাদ দেওয়া হয়। যোগ করে আপনি এই আচরণটি পরিবর্তন করতে পারেন । যাইহোক, এই যখন ব্যবহার কাজ করে না সঙ্গে । ফলশ্রুতিতে খালি বিভাগগুলি রাখার অন্য কোনও উপায় আছে কি?plyrddply.drop = FALSEsummarisedplyr

এখানে নকল তথ্য সহ একটি উদাহরণ।

library(dplyr)

df = data.frame(a=rep(1:3,4), b=rep(1:2,6))

# Now add an extra level to df$b that has no corresponding value in df$a
df$b = factor(df$b, levels=1:3)

# Summarise with plyr, keeping categories with a count of zero
plyr::ddply(df, "b", summarise, count_a=length(a), .drop=FALSE)

  b    count_a
1 1    6
2 2    6
3 3    0

# Now try it with dplyr
df %.%
  group_by(b) %.%
  summarise(count_a=length(a), .drop=FALSE)

  b     count_a .drop
1 1     6       FALSE
2 2     6       FALSE

আমি ঠিক যা আশা করছিলাম তা নয়। dplyrপাশাপাশি একই ফলাফল অর্জনের জন্য কি কোনও পদ্ধতি .drop=FALSEআছে plyr?


উত্তর:


27

যেহেতু dplyr 0.8 group_by আপনার .dropপক্ষে যা চেয়েছিল ঠিক সেভাবে যুক্তি অর্জন করেছে:

df = data.frame(a=rep(1:3,4), b=rep(1:2,6))
df$b = factor(df$b, levels=1:3)

df %>%
  group_by(b, .drop=FALSE) %>%
  summarise(count_a=length(a))

#> # A tibble: 3 x 2
#>   b     count_a
#>   <fct>   <int>
#> 1 1           6
#> 2 2           6
#> 3 3           0

@ মুডি_মডসকিপারের উত্তরটি নিয়ে যাওয়ার জন্য একটি অতিরিক্ত নোট: .drop=FALSEযখন এক বা একাধিক গ্রুপিং ভেরিয়েবলগুলি উপাদান হিসাবে কোডড না করা হয় তখন ব্যবহার সম্ভাব্য অপ্রত্যাশিত ফলাফল দিতে পারে। নীচে উদাহরণ দেখুন:

library(dplyr)
data(iris)

# Add an additional level to Species
iris$Species = factor(iris$Species, levels=c(levels(iris$Species), "empty_level"))

# Species is a factor and empty groups are included in the output
iris %>% group_by(Species, .drop=FALSE) %>% tally

#>   Species         n
#> 1 setosa         50
#> 2 versicolor     50
#> 3 virginica      50
#> 4 empty_level     0

# Add character column
iris$group2 = c(rep(c("A","B"), 50), rep(c("B","C"), each=25))

# Empty groups involving combinations of Species and group2 are not included in output
iris %>% group_by(Species, group2, .drop=FALSE) %>% tally

#>   Species     group2     n
#> 1 setosa      A         25
#> 2 setosa      B         25
#> 3 versicolor  A         25
#> 4 versicolor  B         25
#> 5 virginica   B         25
#> 6 virginica   C         25
#> 7 empty_level <NA>       0

# Turn group2 into a factor
iris$group2 = factor(iris$group2)

# Now all possible combinations of Species and group2 are included in the output, 
#  whether present in the data or not
iris %>% group_by(Species, group2, .drop=FALSE) %>% tally

#>    Species     group2     n
#>  1 setosa      A         25
#>  2 setosa      B         25
#>  3 setosa      C          0
#>  4 versicolor  A         25
#>  5 versicolor  B         25
#>  6 versicolor  C          0
#>  7 virginica   A          0
#>  8 virginica   B         25
#>  9 virginica   C         25
#> 10 empty_level A          0
#> 11 empty_level B          0
#> 12 empty_level C          0

Created on 2019-03-13 by the reprex package (v0.2.1)

আমি আপনার উত্তরে একটি অতিরিক্ত নোট যুক্ত করেছি। আপনি যদি সম্পাদনাটি পছন্দ করেন না তবে নির্দ্বিধায় মুছে ফেলুন।
eipi10

আমি এটি বাগ বা উদ্দেশ্যমূলক আচরণ কিনা তা জানতে গিথুব এ সম্পর্কে একটি সমস্যা দায়ের করেছি ।
eipi10

@ আইপিআই 10 সামান্য খাটো এর ব্যবহার count:iris %>% count(Species, group2, .drop=FALSE)
টেজেবো

59

সমস্যাটি এখনও উন্মুক্ত, তবে এর মধ্যে, বিশেষত যেহেতু আপনার ডেটা ইতিমধ্যে completeফ্যাক্টরড রয়েছে , আপনি "সজ্জা" থেকে আপনি যা খুঁজছেন তা পেতে ব্যবহার করতে পারেন :

library(tidyr)
df %>%
  group_by(b) %>%
  summarise(count_a=length(a)) %>%
  complete(b)
# Source: local data frame [3 x 2]
# 
#        b count_a
#   (fctr)   (int)
# 1      1       6
# 2      2       6
# 3      3      NA

আপনি যদি প্রতিস্থাপনের মানটি শূন্য হতে চান তবে আপনাকে এটির সাথে উল্লেখ করতে হবে fill:

df %>%
  group_by(b) %>%
  summarise(count_a=length(a)) %>%
  complete(b, fill = list(count_a = 0))
# Source: local data frame [3 x 2]
# 
#        b count_a
#   (fctr)   (dbl)
# 1      1       6
# 2      2       6
# 3      3       0

11
এটি চিত্রিত করার জন্য আমাকে প্রাচীরের বিরুদ্ধে প্রচণ্ড মাথা বেঁধেছিল তাই আমি এটি এখানে উল্লেখ করব ... আপনি যদি 2 টি ভেরিয়েবল দ্বারা গোষ্ঠী করেন এবং সেগুলি কারণগুলির চেয়ে অক্ষর হয় ungroup()তবে আপনাকে সম্পূর্ণ করার আগে আপনাকে ব্যবহার করতে হবে । যদি আপনি কখনও লক্ষ্য করেন যে completeবাস্তবে সম্পূর্ণ ungroupহচ্ছে না, সম্ভবত প্রয়োজন।
উইলিয়ামসুরলেস

আপনার যদি আরও আরও গ্রুপিং ভেরিয়েবল থাকে? আমি যদি আমার গ্রুপ_বাজারের সমস্ত গ্রুপিং ভার ব্যবহার করি
টবিও

4
আমি এটি বের করেছিলাম: আপনাকে নেস্টিং ব্যবহার করতে হবে :-) সুতরাং এমন সমস্ত ভেরিয়েবলগুলি রাখুন যা complete(variablewithdroppedlevels, nesting(var1,var2,var3))একে complete
অপরের

20

dplyr সমাধান:

প্রথমে গ্রুপযুক্ত ডিএফ করুন

by_b <- tbl_df(df) %>% group_by(b)

তারপরে আমরা সেই স্তরগুলির সংক্ষিপ্তসার করি যা গণনা করে ঘটে n()

res <- by_b %>% summarise( count_a = n() )

তারপরে আমরা আমাদের ফলাফলগুলিকে একটি ডেটা ফ্রেমে মার্জ করে যাতে সমস্ত ফ্যাক্টর স্তর থাকে:

expanded_res <- left_join(expand.grid(b = levels(df$b)),res)

অবশেষে, এই ক্ষেত্রে যেহেতু আমরা গণনাগুলির দিকে নজর দিচ্ছি NAমানগুলি 0 তে পরিবর্তিত হয়।

final_counts <- expanded_res[is.na(expanded_res)] <- 0

এটি কার্যকরভাবে প্রয়োগ করা যেতে পারে, উত্তরগুলি দেখুন: dplyr এর সাথে গোষ্ঠীযুক্ত ডেটাগুলিতে সারি যুক্ত করুন?

একটি হ্যাক:

আমি ভেবেছিলাম আমি একটি ভয়ঙ্কর হ্যাক পোস্ট করব যা আগ্রহের স্বার্থে এই ক্ষেত্রে কাজ করে। আমি গুরুতরভাবে সন্দেহ করি যে আপনার কখনই আসলে এটি করা উচিত তবে এটি দেখায় যে কীভাবে group_by()অ্যাট্রিবিউটস উত্পন্ন হয় যেন df$bকোনও চরিত্রের ভেক্টর স্তরের কোনও কারণ নয়। এছাড়াও, আমি এটি সঠিকভাবে বোঝার ভান করি না - তবে আমি আশা করছি যে এটি আমাকে শিখতে সহায়তা করবে - এটি পোস্ট করার একমাত্র কারণ!

by_b <- tbl_df(df) %>% group_by(b)

একটি "সীমার বাইরে" মান সংজ্ঞায়িত করুন যা ডেটাসেটে বিদ্যমান থাকতে পারে না।

oob_val <- nrow(by_b)+1

"কৌশল" এ বৈশিষ্ট্যগুলি পরিবর্তন করুন summarise():

attr(by_b, "indices")[[3]] <- rep(NA,oob_val)
attr(by_b, "group_sizes")[3] <- 0
attr(by_b, "labels")[3,] <- 3

সারাংশ করুন:

res <- by_b %>% summarise(count_a = n())

সূচক এবং oob_val এর সমস্ত উপস্থিতি প্রতিস্থাপন

res[res == oob_val] <- 0

যা অভিপ্রায় দেয়:

> res
Source: local data frame [3 x 2]

b count_a
1 1       6
2 2       6
3 3       0

11

এই প্রশ্নটিতে ঠিক যেমনটি জিজ্ঞাসা করা হয়েছিল তা নয়, তবে কমপক্ষে এই সাধারণ উদাহরণের জন্য আপনি অক্স্ট্যাবস ব্যবহার করে একই ফল পেতে পারেন, উদাহরণস্বরূপ:

dplyr ব্যবহার:

df %>%
  xtabs(formula = ~ b) %>%
  as.data.frame()

বা সংক্ষিপ্ত:

as.data.frame(xtabs( ~ b, df))

ফলাফল (উভয় ক্ষেত্রে সমান):

  b Freq
1 1    6
2 2    6
3 3    0
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.