簡體   English   中英

計算屬於一個組的多個值之間的差

[英]Calculate the difference between multiple values belonging to a group

我對R中的一個特定問題有些困惑,對此我只有一個漫不經心而毫無意義的解決方案。 也許有人知道這樣做的更好方法。 可以說我們有一個像這樣的數據框:

x <- c("A", "B", "C", "B", "A", "C", "C", "B", "A", "B", "A", "C")
z <- c(1, 1, 1, 2, 2, 2,3, 3, 3, 4, 4,4)
y <- c(43, 32, 45, 32, 22, 52, 23, 13, 12, 4, 12, 5)
df <- data.frame(x,z,y)

數據如下: plot

我試圖計算取決於z的x分組內的y值之間的差異。 例如,第1組的A和第2組的A(43-22 = 21)與第2組的A和第3組的A(22-12 = 10)之間的差異,依此類推。 我可以這樣做很丑陋:

ordered.df<-df[order(df$z, df$x),]
bl<-ordered.df[ordered.df$z==1,]
bl2<-ordered.df[ordered.df$z==2,]
bl3<-ordered.df[ordered.df$z==3,]
bl4<-ordered.df[ordered.df$z==4,]

first <- bl$y - bl2$y
second <- bl2$y - bl3$y
third <- bl3$y - bl4$y
ycolumn <- c(first,second,third)
xcolumn <- rep(c("A","B","C"),3)
zcolumn <- rep(1:3,each=3)
final.df <- data.frame(xcolumn,zcolumn,ycolumn)

並想知道是否還有更多的電力和可擴展解決方案。

歸根結底,我想算一下正差異的出現:

final.df$lower <- 0
final.df$lower[final.df$ycolumn>0] <- 1
aggregate(lower ~ zcolumn, final.df, sum)

歡迎任何建議! 謝謝!

這是一個data.table單行

setDT(df)[, list(z = z, y_diff = y - shift(y, 1, type = "lead")), by = .(x = x)][ y_diff > 0, list(lower = .N), by = "z"]

#   z lower
#1: 1     1
#2: 2     3
#3: 3     2

它能做什么:
setDT(df)
df制作一個data.table

[, list(z = z, y_diff = y - shift(y, 1, type = "lead")), by = .(x = x)]
用x分組,從當前y中減去下一個y,並使用結果創建列y_diff

[ y_diff > 0, list(lower = .N), by = "z"]
對於y_diff大於0的所有行,給y_diff數(= .N ),按z分組

您可以為每個組使用dplyrmutate

library(dplyr)
final.df <- df %>%
  group_by(x) %>%
  mutate(y = y - lead(y, 1)) %>%
  arrange(z, x) %>%
  filter(!is.na(y))
final.df

# A tibble: 9 x 3
# Groups:   x [3]
  x         z     y
  <fct> <dbl> <dbl>
1 A         1    21
2 B         1     0
3 C         1    -7
4 A         2    10
5 B         2    19
6 C         2    29
7 A         3     0
8 B         3     9
9 C         3    18

並對summarise使用summarise

final.df %>%
  group_by(z) %>%
  summarise(lower = sum(y > 0))
# A tibble: 3 x 2
      z lower
  <dbl> <dbl>
1     1     1
2     2     3
3     3     2

如果實際數據僅具有少量的組(z),但是具有大量的類別(x),則可以將數據轉換為寬格式並從此處開始。 這是簡單示例的解決方案。

> library(data.table)
> library(reshape2)
> 
> df_reshape = dcast(x~z, data=df, value.var="y")
> setDT(df_reshape)
> setnames(df_reshape,c(as.character(seq(1,4,1))),c(paste("x",as.character(seq(1,4,1)), sep="")))
> head(df_reshape)
   x x1 x2 x3 x4
1: A 43 22 12 12
2: B 32 32 13  4
3: C 45 52 23  5
> df_reshape[,.(diff1=x1-x2,diff2=x2-x3,diff3=x3-x4),by=x][,.(group1 = sum(diff1>0),group2 =sum(diff2>0),group3 = sum(diff3>0))]
   group1 group2 group3
1:      1      3      2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM