簡體   English   中英

將一些分組列添加到 R 中的嵌套 dataframe

[英]Add some grouping columns to a nested dataframe in R

我在 R 中有一個帶有 3 列(變量)的 dataframe。 其中一個叫做 Region,是某種嵌套的。 我嘗試復制其中的一小部分。

df <- data.frame (freq = c(70, 72, 74, 76, 78,
                           70, 72, 74, 76, 78,
                           70, 72, 74, 76, 78),
                  region = c('region.1','region.1','region.1','region.1', 'region.1',
                             'region.1.1','region.1.1','region.1.1', 'region.1.1', 'region.1.1',
                             'region.2','region.2', 'region.2', 'region.2', 'region.2'),
                  dBvalue = c(-30, -32, -42, -45, -47,
                              -33, -28, -22, -37, -35,
                              -36, -55, -43, -26, -49))

現在我想添加 3 個新列。 第一個帶有每個區域的觀察計數(因此在這種情況下將是 1...5、1...5 等),第二個必須包含一個分組值 ant 最后一個應該具有更高的層次結構級別在這種情況下,Region 列的聚合最終的 df 將是:

df <- data.frame (freq = c(70, 72, 74, 76, 78,
                           70, 72, 74, 76, 78,
                           70, 72, 74, 76, 78),
                  region = c('region.1','region.1','region.1','region.1', 'region.1',
                             'region.1.1','region.1.1','region.1.1', 'region.1.1', 'region.1.1',
                             'region.2','region.2', 'region.2', 'region.2', 'region.2'),
                  dBvalue = c(-30, -32, -42, -45, -47,
                              -33, -28, -22, -37, -35,
                              -36, -55, -43, -26, -49),
                  count = c(1,2,3,4,5,
                            1,2,3,4,5,
                            1,2,3,4,5),
                  group = c(1,1,1,1,1,
                            2,2,2,2,2,
                            3,3,3,3,3),
                  higher_region = c("region.1","region.1","region.1","region.1","region.1",
                  "region.1","region.1","region.1","region.1","region.1",
                  "region.2","region.2","region.2","region.2","region.2"))

我正在嘗試使用循環功能,但我快瘋了。 有人有解決方案嗎? 也許使用替代方法?

Base中,您可以使用matchunique來查找groupaveseq_along來獲取計數,而strsplitpaste來獲取更高的區域。

df$group <- match(df$region, unique(df$region))
#df$group <- unclass(factor(df$region)) #Alternative
df$count <- ave(df$group, df$region, FUN=seq_along)
df$higher_region <- sapply(strsplit(df$region, ".", TRUE),
 function(x) paste(x[1:2], collapse = "."))
#df$higher_region <- sub("^([^.]+\\.[^.]*).*", "\\1", df$region) #Alternative
df
#   freq     region dBvalue count group higher_region
#1    70   region.1     -30     1     1      region.1
#2    72   region.1     -32     2     1      region.1
#3    74   region.1     -42     3     1      region.1
#4    76   region.1     -45     4     1      region.1
#5    78   region.1     -47     5     1      region.1
#6    70 region.1.1     -33     1     2      region.1
#7    72 region.1.1     -28     2     2      region.1
#8    74 region.1.1     -22     3     2      region.1
#9    76 region.1.1     -37     4     2      region.1
#10   78 region.1.1     -35     5     2      region.1
#11   70   region.2     -36     1     3      region.2
#12   72   region.2     -55     2     3      region.2
#13   74   region.2     -43     3     3      region.2
#14   76   region.2     -26     4     3      region.2
#15   78   region.2     -49     5     3      region.2

建議使用“dplyr”進行分組和計數,以及“as.factor”將區域“重新編碼”為“他第二個必須包含分組值”(盡管這編碼與“區域”相同的信息,也許我誤解了您的規范。最后我們使用“gsub”從“區域”中提取第一個數字

df <- data.frame (freq = c(70, 72, 74, 76, 78,
                           70, 72, 74, 76, 78,
                           70, 72, 74, 76, 78),
                  region = c('region.1','region.1','region.1','region.1', 'region.1',
                             'region.1.1','region.1.1','region.1.1', 'region.1.1', 'region.1.1',
                             'region.2','region.2', 'region.2', 'region.2', 'region.2'),
                  dBvalue = c(-30, -32, -42, -45, -47,
                              -33, -28, -22, -37, -35,
                              -36, -55, -43, -26, -49))

library(dplyr)
df %>% 
  group_by(region) %>% 
  mutate(count = row_number()) %>% 
  ungroup() %>% 
  mutate(group = as.numeric(as.factor(region)),
         higher_region = gsub("[a-z.]*([0-9]).*", "\\1", region)) %>% 
  as.data.frame()

回報:

 freq region dBvalue count group higher_region 1 70 region.1 -30 1 1 1 2 72 region.1 -32 2 1 1 3 74 region.1 -42 3 1 1 4 76 region.1 -45 4 1 1 5 78 region.1 -47 5 1 1 6 70 region.1.1 -33 1 2 1 7 72 region.1.1 -28 2 2 1 8 74 region.1.1 -22 3 2 1 9 76 region.1.1 -37 4 2 1 10 78 region.1.1 -35 5 2 1 11 70 region.2 -36 1 3 2 12 72 region.2 -55 2 3 2 13 74 region.2 -43 3 3 2 14 76 region.2 -26 4 3 2 15 78 region.2 -49 5 3 2

編輯:

占兩位數的“更高地區”:

library(dplyr)
df %>% 
  group_by(region) %>% 
  mutate(count = row_number()) %>% 
  ungroup() %>% 
  mutate(group = as.numeric(as.factor(region)),
         higher_region = gsub("(region.[0-9]+)\\.?.*", "\\1", region)) %>% 
  as.data.frame()


   freq     region dBvalue count group higher_region
1    70   region.1     -30     1     1      region.1
2    72   region.1     -32     2     1      region.1
3    74   region.1     -42     3     1      region.1
4    76   region.1     -45     4     1      region.1
5    78   region.1     -47     5     1      region.1
6    70 region.1.1     -33     1     2      region.1
7    72 region.1.1     -28     2     2      region.1
8    74 region.1.1     -22     3     2      region.1
9    76 region.1.1     -37     4     2      region.1
10   78 region.1.1     -35     5     2      region.1
11   70   region.2     -36     1     3      region.2
12   72   region.2     -55     2     3      region.2
13   74   region.2     -43     3     3      region.2
14   76   region.2     -26     4     3      region.2
15   78   region.2     -49     5     3      region.2

附加選項。 dplyr 1.0.0

library(tidyverse)

df %>% 
  group_by(region) %>% 
  mutate(count = row_number(),
         group = cur_group_id(),
         higher_region = str_extract(region, "^[A-z]*\\.\\d+")) %>% 
  ungroup()

基礎 R 解決方案:

within(df, {
    region_str <- as.character(region)
    higher_region <- ifelse(grepl("[.]\\d[.]", region_str),
                            gsub("[.]\\d$", "", region_str), region_str)
    count <- ave(region_str, region_str, FUN = length)
    rm(region_str)
  }
)

基礎 R 解決方案:

df$count <- unlist(lapply(split(df,df$region), function(x) 1:nrow(x)))
df$group <- unlist(lapply(1:length(unique(df$region)), function(x) rep(x, nrow(split(df,df$region)[[x]]))))
df$higher_region <- sub("(region\\.\\d+).*","\\1",df$region)

> df
   freq     region dBvalue count group higher_region
1    70   region.1     -30     1     1      region.1
2    72   region.1     -32     2     1      region.1
3    74   region.1     -42     3     1      region.1
4    76   region.1     -45     4     1      region.1
5    78   region.1     -47     5     1      region.1
6    70 region.1.1     -33     1     2      region.1
7    72 region.1.1     -28     2     2      region.1
8    74 region.1.1     -22     3     2      region.1
9    76 region.1.1     -37     4     2      region.1
10   78 region.1.1     -35     5     2      region.1
11   70   region.2     -36     1     3      region.2
12   72   region.2     -55     2     3      region.2
13   74   region.2     -43     3     3      region.2
14   76   region.2     -26     4     3      region.2
15   78   region.2     -49     5     3      region.2

暫無
暫無

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

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