Dplyr คำนวณค่าเฉลี่ยและความแปรปรวนโดยไม่มีข้อมูลทั้งหมด

ฉันมีชุดข้อมูลที่เริ่มต้นดังนี้:

set.seed(50)
n <- 20
s_num <- c(10,20,30)
counts <- c(0,1,2,3,4)

strata <- sample(s_num, n, replace=T)
sites <- seq(1, n, by=1)
observed <- sample(counts, n, replace=T)

df <- as.data.frame(cbind(strata,sites,observed))

ฉันสามารถจัดกลุ่มตามชั้นและรับค่าเฉลี่ยและความแปรปรวนโดยใช้ dplyr โดย:

library(dplyr)
df2 <- df %>%
  group_by(strata) %>%
  summarise(mcount = mean(observed),
            varcount = var(observed))

ปัญหาคือ 0 จำนวนไม่อยู่ในฐานข้อมูลอีกต่อไป:

df3 <- subset(df,observed != 0)

ดังนั้นค่าเฉลี่ยและความแปรปรวนจึงไม่ถูกต้อง:

df4 <- df3 %>%
  group_by(strata) %>%
  summarise(mcount = mean(observed),
            varcount = var(observed))

แต่ฉันมีจำนวนไซต์:

site_count <- df %>%
  group_by(strata) %>%
  summarise(count_plot = n_distinct(sites))

ฉันยังสามารถใช้ dplyr เพื่อคำนวณความแปรปรวนเฉลี่ยโดยไม่มี 0 ได้หรือไม่ ความหมายจริงๆ แล้วไม่ยากเกินไปด้วยการรวมจำนวนไซต์เป็น df; ความแปรปรวนนั้นยากกว่า ฉันสามารถเพิ่ม 0 แถวกลับเข้าไปได้หากจำเป็น แต่ต้องการดูว่ามีวิธีง่ายๆ ในการแก้ไขหรือไม่หากเป็นไปได้ ขอบคุณ.


person tjr    schedule 20.06.2018    source แหล่งที่มา


คำตอบ (3)


คุณสามารถคำนวณค่าเฉลี่ยและความแปรปรวนจากสูตรได้ด้วยตนเอง เมื่อคุณคำนวณ count_plot แล้ว

ความแปรปรวนคำนวณเป็น sum((x - mean(x))^2)/(length(x) - 1)

df3 %>% 
  left_join(site_count) %>% 
  group_by(strata) %>%
  summarise(N        = unique(count_plot),
            mcount   = sum(observed)/N,
            varcount = sum((observed - mcount)^2, (N - n())*mcount^2)/(N - 1)) %>% 
  select(-N)


# # A tibble: 3 x 3
#   strata mcount varcount
#    <dbl>  <dbl>    <dbl>
# 1   10.0   1.89    0.861
# 2   20.0   1.33    1.07 
# 3   30.0   2.40    2.30 

ซึ่งตรงกับ df2

df2

# A tibble: 3 x 3
  strata mcount varcount
   <dbl>  <dbl>    <dbl>
1   10.0   1.89    0.861
2   20.0   1.33    1.07 
3   30.0   2.40    2.30 
person IceCreamToucan    schedule 20.06.2018
comment
เยี่ยมเลย ขอบคุณ ฉันไม่แน่ใจว่า sum(()) จะใช้ได้สำหรับแต่ละแถวหรือไม่ แต่ใช้งานได้ - person tjr; 20.06.2018

คุณสามารถเพิ่ม filter ลงในไปป์ไลน์ของคุณได้

df2 <- df %>%
 filter(observed != 0) %>%
 group_by(strata) %>%
 summarise(mcount = mean(observed),
          varcount = var(observed))

วิธีนี้ทำให้คุณไม่จำเป็นต้องสร้างดาต้าเฟรมระดับกลาง

person Adarsh Chavakula    schedule 20.06.2018
comment
อันนี้หรูหรากว่า - person akrun; 20.06.2018
comment
จากสิ่งที่ฉันบอกได้ คำถามคือถามว่าจะคำนวณค่าเฉลี่ยและความแปรปรวนโดยไม่ใช้ df ได้อย่างไร - person IceCreamToucan; 20.06.2018
comment
ใช่ ขออภัย ฉันไม่ชัดเจน ฉันไม่มี df ดั้งเดิมในกรณีนี้ - person tjr; 20.06.2018

เราสามารถสร้างเงื่อนไขตรรกะให้กับเซตย่อยได้

df %>%
   mutate(ind = observed != 0) %>%
   group_by(strata) %>%
   summarise(mcount = mean(observed[ind]), varcount = var(observed[ind]))
# A tibble: 3 x 3
#  strata mcount varcount
#   <dbl>  <dbl>    <dbl>
#1     10   1.89    0.861
#2     20   1.6     0.8  
#3     30   3       0.667

หมายเหตุ: ไม่แนะนำให้ใช้ as.data.frame(cbind เนื่องจาก cbind สามารถแปลงเป็น matrix (เมทริกซ์สามารถเก็บได้เพียงคลาสเดียว) ซึ่งจะทำให้คอลัมน์ทั้งหมด factor หรือ character มี as.data.frame (หากมีคอลัมน์อักขระใดๆ) ให้ใช้ data.frame(strata, sites, observed) แทน

person akrun    schedule 20.06.2018