我的数据框如下,
df <- read.table(text="Name value
A 0
A 1
A 2
A 3
B 0
B 0
B 3
C 5", header=T)
> df
Name value
1 A 0
2 A 1
3 A 2
4 A 3
5 B 0
6 B 0
7 B 3
8 C 5
我最初想要将bin分配给每个名称的最大值,因此我这样做了,
p = df %>% group_by(Name) %>% summarise(k =max(value))
p$values <- as.character(cut(p$k, breaks=c(0,1,2,3,4,5,10), labels=c("0-1","1-2","2-3","3-4","4-5","5-10")))
获得以下输出,
> p
Source: local data table [3 x 3]
Name k values
(fctr) (int) (chr)
1 A 3 2-3
2 B 3 2-3
3 C 5 4-5
现在我想通过值对其进行分组,以查看分割箱。因此,我尝试了以下内容,
> p %>% group_by(values) %>% summarise(n())
Source: local data table [2 x 2]
values n()
(chr) (int)
1 2-3 2
2 4-5 1
现在在2-3个箱内,计数为2,它是A&amp; B.在4-5内,计数为1,C在其后面。现在我想为此输出添加另一列。输出应该是第一行中原始数据帧DF中的A和B的总行数以及第二行中的C行数。
我正在寻找的输出是,
values n() totalcount
(chr) (int)
1 2-3 2 6
2 4-5 1 1
其中6和1是n()计数内的行数。我被困在创建第三列。有人可以帮我或提供一些建议吗?
由于
答案 0 :(得分:2)
data.table
我发现这种事情更容易:
# convert to data table
library(data.table)
dt <- data.table(df)
# find max by Name
p <- dt[, list(k=max(value)), by='Name']
# label maxes
breaks <- c(0,1,2,3,4,5,10)
labels <- c("0-1","1-2","2-3","3-4","4-5","5-10")
for (b in breaks) p[k==b, values:=labels[breaks==b]]
# count the Names within each bin
n <- p[, list(n=.N), by='values']
# count rows in original data table by bin
dt <- merge(dt, p, 'Name')
totalcount <- dt[, list(totalcount=.N), by='values']
# assemble n and totalcount to produce final output
n <- merge(n, totalcount, 'values')
答案 1 :(得分:2)
这是另一个data.table实现:
dt[, .(N=.N, value=max(value)), Name
][, bin := cut(value,
breaks=c(0,1,2,3,4,5,10),
labels=c("0-1","1-2","2-3","3-4","4-5","5-10"))
][, .(N=.N, NRows=sum(N)), bin
]
答案 2 :(得分:1)
我们可以在管道(%>%
)内完成大部分作业。例如,使用p$values <- ...
代替mutate
来创建一列“值”&#39;。按照“值”分组后,我们再次mutate
创建“&n”这样的名字就是&#39;列保留在数据集中,该数据集可用作left_join
中与原始数据集(&#39; df&#39;)一起使用的公共变量。之后,我们join
使用summarise
获取&{39} n&#39;的first
值。以&#39;值&#39;分组的行数(&#39; totalcount&#39;)。
df %>%
group_by(Name) %>%
summarise(k=max(value)) %>%
mutate(values = cut(k, breaks= c(0,1,2,3,4,5,10),
labels=c("0-1","1-2","2-3","3-4","4-5","5-10"))) %>%
group_by(values) %>%
mutate(n=n()) %>%
left_join(., df, by ='Name') %>%
group_by(values) %>%
summarise(n=first(n), totalcount=n())
# values n totalcount
# (fctr) (int) (int)
#1 2-3 2 7
#2 4-5 1 1