سؤال

كنت تريد أن تكون قادرة على summarize وهو تجميع البيانات الإطار حيث لا يعرفون دائما ما المتغيرات التي سوف تكون موجودة, ولكن أنا لا أعرف كيف أريد أن ألخص كل متغير إذا كان موجودا.

دعونا نقول لدي dataframe على هذا النحو:

df <- data.frame(id = c(rep('a', 5), rep('b', 8), rep('c', 4)),
                 var1 = round(runif(17) * 10, 3),
                 var2 = sample(c(1:4), 17, replace = TRUE),
                 var4 = sample(1:1000, 17))
> df

   id  var1 var2 var4
1   a 5.930    4  360
2   a 7.265    2  713
3   a 3.704    3  117
4   a 5.149    2  782
5   a 3.777    2  640
6   b 4.183    2  802
7   b 0.107    2  638
8   b 5.323    4  327
9   b 4.322    2  631
10  b 0.937    3  921
11  b 5.558    2  570
12  b 5.902    4  363
13  b 0.671    3  432
14  c 0.475    1  845
15  c 1.562    3  620
16  c 4.464    2  997
17  c 1.714    2  714

إشعار var3 مفقود.أحيانا يكون هناك في بعض الأحيان أنها ليست.انها دائما نفس النوع عندما كان موجودا.وأود أن تكون قادرة على بدقة التعامل مع كل الحالات.

دعنا نقول أن يلخص من قبل id, أريد الحصول على متوسط var1, متوسط var2, متوسط var3 (عندما تكون موجودة) و ماكس من var4.إذا كان كل المتغيرات الحالية لا يمكن إعداده مثل هذا:

library('dplyr')
set.seed(111)
result <- df %>% group_by(id) %>%
  summarize(var1 = mean(var1),
            var2 = median(var2),
            var3 = median(var3),
            var4 = max(var4))

ومع ذلك ، منذ var3 ليس هناك أحصل على خطأ: Error in median(var3) : object 'var3' not found.

حدسي, وأود أن محاولة شيء من هذا القبيل:

result <- df %>% group_by(id) %>%
  summarize(if('var1' %in% names(df)) var1 = mean(var1) else NULL,
            if('var2' %in% names(df)) var2 = median(var2) else NULL,
            if('var3' %in% names(df)) var3 = median(var3) else NULL,
            if('var4' %in% names(df)) var4 = max(var4) else NULL)

ولكن من الواضح أنه لا يعمل أو ربما الحدس بلدي قليلا قبالة.

هل من أحد لديه أي اقتراحات بشأن كيف يمكن تحقيق هذه نظيفة باستخدام dplyr?كما كنت قد تخمين ، df في الواقع هي البيانات الكبيرة الإطار مع العديد من الأعمدة ، var3 هي واحدة من أي عدد الأعمدة التي يمكن أن تكون في عداد المفقودين.

هل كانت مفيدة؟

المحلول

ليس بالضبط هذا هو الحل, ولكن ربما الحل, إذا كنت لا ترغب في خلق كل شيء ممكن الأعمدة مقدما كما اقترح @joran.فإنه سيتم إنشاء أول كل الأعمدة يمكنك تحديد ولكن البعض منهم سوف يكون فقط NA.بعد ذلك هل يمكن حذف الأعمدة باستخدام تطبيق.علما أن names(dd), عندما تستخدم داخل dplyr سلسلة يعترف إلا أسماء الأعمدة التي كانت في إدخال البيانات.الإطار ، وليس تلك التي تم إنشاؤها في نفس العملية.

dd <- dd %>% 
  group_by(id) %>%
  summarize(var1 = ifelse("var1" %in% names(dd), mean(var1), NA),
            var2 = ifelse("var2" %in% names(dd), max(var2), NA))  

dd <- dd[,apply(dd, 2, function(x) ifelse(all(is.na(x)), FALSE, TRUE))]

آخر محتمل الحل يمكن أن يكون استخدام summarise_each وظيفة ولكن أعتقد أن ذلك يعتمد على ما إذا كنت تريد ، على سبيل المثال،, متوسط و ماكس من جميع الأعمدة أم لا.

نصائح أخرى

أعتقد أنك يمكن أن تفعل هذا في عدة خطوات:

  1. التحويل من واسعة طويلة باستخدام melt
  2. تلخيص باستخدام dplyr
  3. التحويل من فترة طويلة واسعة باستخدام dcast

على سبيل المثال:

tmp <- melt(df, id.vars="id")

tmp <- tmp %>%
  group_by(id, variable) %>%
  summarise(mean = mean(value), median = median(value), max = max(value))

tmp <- melt(tmp, id.vars=c("id", "variable"), variable.name="stat")

tmp <- dcast(tmp, id ~ stat + variable)

كان لي أن أضيف خطوة إضافية لأنك تريد, متوسط, و ماكس المتغيرات المختلفة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top