[英]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中,您可以使用match
和unique
來查找group , ave
和seq_along
來獲取計數,而strsplit
和paste
來獲取更高的區域。
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.