Dplyr সহ একাধিক কলাম জুড়ে যোগফল


98

আমার প্রশ্নে ডেটা ফ্রেমের একাধিক কলামে মানগুলি যোগ করা এবং এই সংমিশ্রণের সাথে মিল রেখে একটি নতুন কলাম তৈরি করা জড়িত dplyr। কলামগুলিতে ডেটা এন্ট্রিগুলি বাইনারি (0,1) হয়। আমি এর summarise_eachবা mutate_eachফাংশনের সারি-অনুসারে এনালগের কথা ভাবছি dplyr। নীচে ডেটা ফ্রেমের একটি সর্বনিম্ন উদাহরণ দেওয়া হল:

library(dplyr)
df=data.frame(
  x1=c(1,0,0,NA,0,1,1,NA,0,1),
  x2=c(1,1,NA,1,1,0,NA,NA,0,1),
  x3=c(0,1,0,1,1,0,NA,NA,0,1),
  x4=c(1,0,NA,1,0,0,NA,0,0,1),
  x5=c(1,1,NA,1,1,1,NA,1,0,1))

> df
   x1 x2 x3 x4 x5
1   1  1  0  1  1
2   0  1  1  0  1
3   0 NA  0 NA NA
4  NA  1  1  1  1
5   0  1  1  0  1
6   1  0  0  0  1
7   1 NA NA NA NA
8  NA NA NA  0  1
9   0  0  0  0  0
10  1  1  1  1  1

আমি এরকম কিছু ব্যবহার করতে পারি:

df <- df %>% mutate(sumrow= x1 + x2 + x3 + x4 + x5)

তবে এটিতে প্রতিটি কলামের নাম লেখা জড়িত। আমার কাছে 50 টি কলাম রয়েছে। এছাড়াও কলামের নামগুলি লুপের বিভিন্ন পুনরাবৃত্তিতে পরিবর্তিত হয় যেখানে আমি এই ক্রিয়াকলাপটি বাস্তবায়ন করতে চাই তাই আমি কোনও কলামের নাম না দেওয়ার চেষ্টা করতে চাই।

আমি কীভাবে সবচেয়ে দক্ষতার সাথে এটি করতে পারি? কোন সহায়তা ব্যাপকভাবে প্রশংসা হবে।


11
কেন dplyr? df$sumrow <- rowSums(df, na.rm = TRUE)বেস বেস থেকে কেবল সরল নয় কেন ? অথবা df$sumrow <- Reduce(`+`, df)আপনি যদি সঠিক কাজটি করেছেন তার প্রতিলিপি করতে চান dplyr
ডেভিড আরেনবার্গ

7
আপনি উভয়ই dplyrতেমন হিসাবে df %>% mutate(sumrow = Reduce(`+`, .))বাdf %>% mutate(sumrow = rowSums(.))
ডেভিড আরেনবুর্গ

4
সর্বশেষতম dplyrসংস্করণে আপডেট করুন এবং এটি কাজ করবে।
ডেভিড আরেনবুর্গ

4
ডেভিড Arenburg দ্বারা প্রস্তাবনা @DavidArenburg dplyr আপডেট প্যাকেজ পর কাজ
AMO

4
@ বার্ন ডেভিড অ্যারেনবার্গস মন্তব্যটি ছিল সেরা উত্তর এবং সর্বাধিক প্রত্যক্ষ সমাধান। আপনার উত্তরটি কার্যকর হবে তবে এটিতে শূন্যের সাথে এনএ মানগুলি প্রতিস্থাপনের একটি অতিরিক্ত পদক্ষেপ জড়িত যা কিছু ক্ষেত্রে উপযুক্ত নাও হতে পারে।
amo

উত্তর:


112

কেমন

প্রতিটি কলাম যোগফল

df %>%
   replace(is.na(.), 0) %>%
   summarise_all(funs(sum))

প্রতিটি সারি যোগফল

df %>%
   replace(is.na(.), 0) %>%
   mutate(sum = rowSums(.[1:5]))

8
summarise_eachপ্রতিটি কলামের যখন কি প্রয়োজন বোধ করা হয় প্রতিটি সারির বরাবর সমষ্টি বরাবর নিচে অঙ্কের
AMO

4
আমি এটি অর্জন করার চেষ্টা করছি, তবে আমার ডিএফের একটি কলাম রয়েছে যা একটি চরিত্র, তাই আমি সমস্ত কলামগুলিকে যোগ করতে পারি না। আমি অনুমান করি যে আমার (.[1:5])অংশটি পরিবর্তন করা উচিত , তবে দুর্ভাগ্যক্রমে আমি সিনট্যাক্সের সাথে পরিচিত নই এবং এটিতে কীভাবে সহায়তা খুঁজতে হয় তা আমি জানি না। চেষ্টা করেও mutate(sum = rowSums(is.numeric(.)))কাজ হয়নি।
চকামারা

4
আমি দেখি. আপনি df %>% replace(is.na(.), 0) %>% select_if(is.numeric) %>% summarise_each(funs(sum))একটি শট দিতে চান ?
বোর্ন

4
এটি হ্রাস করা হয়েছে তার summarise_allপরিবর্তে ব্যবহার করুন summarise_each
hmhensen

4
আপনার কয়টি mutate(sum = rowSums(.[,-1]))কলামের সাথে ডিল করতে হবে তা আপনি যদি না জানেন তবে সিনট্যাক্সটি কার্যকর হতে পারে।
পাওলো এস আব্রেউ

32

আপনি যদি কিছু নির্দিষ্ট কলামগুলি কেবলমাত্র যোগ করতে চান তবে আমি এই জাতীয় কিছু ব্যবহার করব:

library(dplyr)
df=data.frame(
  x1=c(1,0,0,NA,0,1,1,NA,0,1),
  x2=c(1,1,NA,1,1,0,NA,NA,0,1),
  x3=c(0,1,0,1,1,0,NA,NA,0,1),
  x4=c(1,0,NA,1,0,0,NA,0,0,1),
  x5=c(1,1,NA,1,1,1,NA,1,0,1))
df %>% select(x3:x5) %>% rowSums(na.rm=TRUE) -> df$x3x5.total
head(df)

এইভাবে আপনি dplyr::selectএর সিনট্যাক্স ব্যবহার করতে পারেন ।


আমি এই পদ্ধতিকে অন্যদের চেয়ে পছন্দ করি যেহেতু এটির জন্য এনএ-তে 0 জোর করা দরকার না
মাইকেল বেলহাউস

এবং গ্রেপের চেয়ে ভাল কারণ x4: x11
ডভ রোজেনবার্গ

32

আমি নির্দিষ্ট প্যাটার্ন নামের সাথে ভেরিয়েবলের যোগফলের জন্য নিয়মিত প্রকাশের মিলটি ব্যবহার করব। উদাহরণ স্বরূপ:

df <- df %>% mutate(sum1 = rowSums(.[grep("x[3-5]", names(.))], na.rm = TRUE),
                    sum_all = rowSums(.[grep("x", names(.))], na.rm = TRUE))

আপনি আপনার ডেটা ফ্রেমের নির্দিষ্ট গ্রুপের ভেরিয়েবলের যোগফল হিসাবে একাধিক ভেরিয়েবল তৈরি করতে পারেন।


দুর্দান্ত সমাধান! আমি সাম্প্রতিক প্রকাশগুলিতে এটি করে একটি নির্দিষ্ট dplyr ফাংশন সন্ধান করছিলাম, কিন্তু খুঁজে
পাই না

এই সমাধান দুর্দান্ত। যদি কলামগুলি থাকে তবে আপনি এটি অন্তর্ভুক্ত করতে চান না কোনও নির্দিষ্ট প্যাটার্নের সাথে মিলিয়ে কলামগুলি নির্বাচন করার জন্য আপনাকে কেবল গ্রেপ () বিবৃতি ডিজাইন করতে হবে।
ট্রেনটন হফম্যান

4
@ ট্রেনটনহফম্যান এখানে বিটটি নির্দিষ্ট প্যাটার্নটিকে অনির্বাচিত করেছে। শুধু -সাইন দরকার :rowSums(.[-grep("x[3-5]", names(.))], na.rm = TRUE)
alexb523

22

আমি প্রায়শই এই সমস্যার মুখোমুখি হই এবং এটি করার সবচেয়ে সহজ উপায় হ'ল apply()একটি mutateকমান্ডের মধ্যে ফাংশনটি ব্যবহার করা ।

library(tidyverse)
df=data.frame(
  x1=c(1,0,0,NA,0,1,1,NA,0,1),
  x2=c(1,1,NA,1,1,0,NA,NA,0,1),
  x3=c(0,1,0,1,1,0,NA,NA,0,1),
  x4=c(1,0,NA,1,0,0,NA,0,0,1),
  x5=c(1,1,NA,1,1,1,NA,1,0,1))

df %>%
  mutate(sum = select(., x1:x5) %>% apply(1, sum, na.rm=TRUE))

আপনি এখানে স্ট্যান্ডার্ড dplyrট্রিকস (যেমন starts_with()বা contains()) ব্যবহার করে কলামগুলি নির্বাচন করতে চান তা ব্যবহার করতে পারেন । একটি mutateকমান্ডের মধ্যে সমস্ত কাজ করে , এই ক্রিয়াটি dplyrপ্রক্রিয়াজাতকরণের ধাপগুলির প্রবাহের মধ্যে যে কোনও জায়গায় ঘটতে পারে । পরিশেষে, apply()ফাংশনটি ব্যবহার করে , আপনার নিজের উদ্দেশ্যে নির্মিত সংক্ষিপ্তকরণ ফাংশন সহ আপনার যা প্রয়োজন সংক্ষিপ্তসার প্রয়োজন তা ব্যবহার করার নমনীয়তা আপনার রয়েছে।

বিকল্পভাবে, যদি একটি নন-টিডিভার্স ফাংশন ব্যবহারের ধারণাটি আবেদনময়ী হয়, তবে আপনি কলামগুলি সংগ্রহ করতে পারেন, সেগুলি সংক্ষিপ্ত করতে পারেন এবং শেষ পর্যন্ত ফলাফলটিতে মূল ডেটা ফ্রেমে ফিরে যেতে পারেন।

df <- df %>% mutate( id = 1:n() )   # Need some ID column for this to work

df <- df %>%
  group_by(id) %>%
  gather('Key', 'value', starts_with('x')) %>%
  summarise( Key.Sum = sum(value) ) %>%
  left_join( df, . )

এখানে আমি starts_with()কলামগুলি নির্বাচন করতে ফাংশনটি ব্যবহার করেছি এবং যোগফলটি গণনা করেছি এবং আপনি NAমানগুলির সাথে যা চান তা করতে পারেন । এই পদ্ধতির নেতিবাচক দিকটি হ'ল এটি বেশ নমনীয় হলেও এটি dplyrডেটা সাফ করার পদক্ষেপগুলির একটি স্ট্রিমের সাথে সত্যই ফিট করে না ।


4
এটি applyযখন rowSumsডিজাইনের জন্য তৈরি করা হয়েছিল তখন ব্যবহার করার মতো নির্বোধ মনে হয় ।
জ্যাকডাভ

6
এই ক্ষেত্রে rowSumsসত্যিই ভাল কাজ করে যেমন করে rowMeans, কিন্তু আমি সবসময় অনুভূত একটু অদ্ভুত সম্পর্কে হতাশ "কি যদি জিনিস আমি ক্যালকুলেট করার প্রয়োজন হয়, সমষ্টি বা একটি গড় নয়?" যাইহোক, 99% সময় আমাকে এই জাতীয় কিছু করতে হয়, এটি হয় একটি যোগফল বা গড়, তাই সম্ভবত সাধারণ applyফাংশনটি ব্যবহারের ক্ষেত্রে অতিরিক্ত বিস্তৃততা সজ্জিত নয়।
ডেরেক সোনডেগ্রেগার

22

এর reduce()থেকে ব্যবহার করা তার থেকে purrrকিছুটা দ্রুত rowSumsএবং স্পষ্টতই দ্রুততর apply, যেহেতু আপনি সমস্ত সারিগুলিতে পুনরাবৃত্তি এড়াতে এবং কেবল ভেক্টরাইজড ক্রিয়াকলাপগুলির সুবিধা নেবেন:

library(purrr)
library(dplyr)
iris %>% mutate(Petal = reduce(select(., starts_with("Petal")), `+`))

দেখুন এই সময় জন্য


আমি এটি পছন্দ করি তবে আপনি যখন প্রয়োজন তখন এটি কীভাবে করবেনna.rm = TRUE
24

@ see24 আমি নিশ্চিত না আপনি কী বলতে চাইছেন তা আমি জানি। এই একই দৈর্ঘ্যের সমস্ত ভেক্টরকে a + b + c পরিমাণ যোগ করে। যেহেতু প্রতিটি ভেক্টরের বিভিন্ন স্থানে এনএ থাকতে পারে বা নাও থাকতে পারে, তাই আপনি এগুলি উপেক্ষা করতে পারবেন না। এটি ভেক্টরকে স্বাক্ষরবিহীন করে তুলবে। আপনি যদি এনএ মানগুলি মুছে ফেলতে চান তবে এটির পরে আপনার উদাহরণস্বরূপ করতে হবে , ড্রপ_না
স্কেড

আমি শেষ করেছিলাম rowSums(select(., matches("myregex")) , na.rm = TRUE))কারণ এন.এ.এস. উপেক্ষা করার ক্ষেত্রে এটিই আমার প্রয়োজন ছিল। সুতরাং যদি সংখ্যাগুলি হয় sum(NA, 5)ফলাফলগুলি 5 হয় তবে আপনি বলেছিলেন যে হ্রাস কম ভাল rowSumsতাই আমি ভাবছিলাম এই পরিস্থিতিতে এটি ব্যবহার করার কোনও উপায় আছে কিনা?
24

আমি দেখি. আপনি যদি যোগফল চান এবং এনএ মানগুলি উপেক্ষা করতে চান তবে rowSumsসংস্করণটি সম্ভবত সেরা। প্রধান অসুবিধাটি হ'ল কেবল rowSumsএবং rowMeansউপলভ্য (এটি হ্রাস করার চেয়ে কিছুটা ধীরে ধীরে ধীরে ধীরে কম তবে বেশি নয়)। আপনার যদি অন্য অপারেশন করতে হবে (যোগফল নয়) তবে reduceসংস্করণটি সম্ভবত একমাত্র বিকল্প। শুধু applyএই ক্ষেত্রে ব্যবহার এড়ানো ।
skd

1

এর নতুন সংস্করণে dplyrআপনি ব্যবহার করতে পারেন rowwise()সহ c_acrossফাংশন নির্দিষ্ট সারি ভিত্তিক রূপগুলো হবে না যে জন্য সারি ভিত্তিক অ্যাগ্রিগেশন সম্পাদন করতে, কিন্তু যদি সারি ভিত্তিক বৈকল্পিক বিদ্যমান এটি দ্রুত হওয়া উচিত।

যেহেতু rowwise()কেবলমাত্র গ্রুপিংয়ের একটি বিশেষ ফর্ম এবং ক্রিয়াপদের কাজ করার পদ্ধতি পরিবর্তন করে আপনি সম্ভবত ungroup()আপনার সারি অনুসারে অপারেশন করার পরে এটিটি পাইপ করতে চাইবেন ।

সারিগুলির একটি ব্যাপ্তি নির্বাচন করতে:

df %>%
  dplyr::rowwise() %>% 
  dplyr::mutate(sumrange = sum(dplyr::c_across(x1:x5), na.rm = T))
# %>% dplyr::ungroup() # you'll likely want to ungroup after using rowwise()

টাইপ করে সারি নির্বাচন করতে:

df %>%
  dplyr::rowwise() %>% 
  dplyr::mutate(sumnumeric = sum(c_across(where(is.numeric)), na.rm = T))
# %>% dplyr::ungroup() # you'll likely want to ungroup after using rowwise()

আপনার নির্দিষ্ট ক্ষেত্রে একটি সারি-ভিত্তিক বৈকল্পিক উপস্থিত রয়েছে যাতে আপনি নিম্নলিখিতটি করতে পারেন ( acrossপরিবর্তে এর ব্যবহারটি নোট করুন ):

df %>%
  dplyr::mutate(sumrow = rowSums(dplyr::across(x1:x5), na.rm = T))
# %>% dplyr::ungroup() # you'll likely want to ungroup after using rowwise()

আরও তথ্যের জন্য পৃষ্ঠাটি সারিবদ্ধভাবে দেখুন

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