我有一个像这样的数据框:
df<- data.frame(region = c("1","1","1","1","1","2","2"),
loc = c("104","104","104","105","105","106","107"),
plntsp = c("A","A", "B", "C", "C", "E", "F"),
lepsp = c("Z","Z", "Y", "W", "X", "T", "T"))
我想:
1)找到每个plntsp
和lepsp
子集的region
和loc
的频率。
2)将plantsp
和lepsp
列折叠为一列标题为sp
的长数据框。新计数列将折叠为一个名为freq
的计数列。
output<- data.frame(region = c("1","1","1","1","2","1","1","1","2","2","2"),
loc = c("104","104","105","106","107","104","104","105","105","106","107"),
sp = c("A","B", "C", "E", "F", "Z", "Y","W", "X", "T", "T"),
freq = c("2","1", "2", "1", "1", "2", "1", "1", "1", "1", "1"))
我试过了:
df<-
group_by(region,loc) %>%
summarise(freq1= length(unique(plantsp), freq2= length(unique(lepsp))
mutate(sp= df$plantsp &df$lepsp, freq= df$freq1 &df$freq2)
答案 0 :(得分:1)
aggregate
将是一个选项
rbind(aggregate(list(freq = seq_along(df$plntsp)),
by = list(region = df$region,loc = df$loc, sp = df$plntsp),
FUN = length),
aggregate(list(freq = seq_along(df$plntsp)),
by = list(region = df$region, loc = df$loc, sp = df$lepsp),
FUN = length))
# region loc sp freq
#1 1 104 A 2
#2 1 104 B 1
#3 1 105 C 2
#4 2 106 E 1
#5 2 107 F 1
#6 2 106 T 1
#7 2 107 T 1
#8 1 105 W 1
#9 1 105 X 1
#10 1 104 Y 1
#11 1 104 Z 2
在使用melt
reshape2
aggregate
library(reshape2)
opt = melt(data = df, id.vars = c("region", "loc"))
#Warning message:
#attributes are not identical across measure variables; they will be dropped
aggregate(list(freq=opt$value), opt[c("region","loc","value")], FUN = length)
# region loc value freq
#1 1 104 A 2
#2 1 104 B 1
#3 1 105 C 2
#4 2 106 E 1
#5 2 107 F 1
#6 2 106 T 1
#7 2 107 T 1
#8 1 105 W 1
#9 1 105 X 1
#10 1 104 Y 1
#11 1 104 Z 2
答案 1 :(得分:1)
使用tidyverse
:
library(tidyverse)
df %>%
gather(key, sp, plntsp, lepsp) %>%
group_by(region, loc, sp) %>%
count(.) %>%
rename(x=n)
region loc sp x
1 1 104 A 2
2 1 104 B 1
3 1 104 Y 1
4 1 104 Z 2
5 1 105 C 2
6 1 105 W 1
7 1 105 X 1
8 2 106 E 1
9 2 106 T 1
10 2 107 F 1
11 2 107 T 1
答案 2 :(得分:0)
此data.table
解决方案遵循the advice from thelatemail首先重新构造为长格式,然后计算外观。
可以从两个软件包中获取melt()
从宽到长格式重塑数据的功能:reshape2
和data.table
。出于性能原因和简洁的语法,我更喜欢后者:
library(data.table)
id_vars = c("region", "loc")
melt(setDT(df), id.vars = id_vars, value.name = "sp")[, .(freq = .N), c(id_vars, "sp")]
region loc sp freq 1: 1 104 A 2 2: 1 104 B 1 3: 1 105 C 2 4: 2 106 E 1 5: 2 107 F 1 6: 1 104 Z 2 7: 1 104 Y 1 8: 1 105 W 1 9: 1 105 X 1 10: 2 106 T 1 11: 2 107 T 1
请注意,列已根据OP的请求重命名。为了与远程发布的其他答案进行比较,代码更加精简,无需重命名列:
melt(setDT(df), id.vars = id_vars)[, .N, c(id_vars, "value")]