我正在尝试从特定类型的数据创建列联表。这对于循环等是可行的......但是因为我的最终表将包含超过10E5的单元格,所以我正在寻找一个预先存在的函数。
我的初步数据如下:
PLANT ANIMAL INTERACTIONS
---------------------- ------------------------------- ------------
Tragopogon_pratensis Propylea_quatuordecimpunctata 1
Anthriscus_sylvestris Rhagonycha_nigriventris 3
Anthriscus_sylvestris Sarcophaga_carnaria 2
Heracleum_sphondylium Sarcophaga_carnaria 1
Anthriscus_sylvestris Sarcophaga_variegata 4
Anthriscus_sylvestris Sphaerophoria_interrupta_Gruppe 3
Cerastium_holosteoides Sphaerophoria_interrupta_Gruppe 1
我想创建一个这样的表:
Propylea_quatuordecimpunctata Rhagonycha_nigriventris Sarcophaga_carnaria Sarcophaga_variegata Sphaerophoria_interrupta_Gruppe
---------------------- ----------------------------- ----------------------- ------------------- -------------------- -------------------------------
Tragopogon_pratensis 1 0 0 0 0
Anthriscus_sylvestris 0 3 2 4 3
Heracleum_sphondylium 0 0 1 0 0
Cerastium_holosteoides 0 0 0 0 1
也就是说,所有植物种类在行中,所有动物种类在列中,有时没有相互作用(而我的初始数据仅列出发生的相互作用)。
答案 0 :(得分:33)
在基数R中,使用table
或xtabs
:
with(warpbreaks, table(wool, tension))
tension
wool L M H
A 9 9 9
B 9 9 9
xtabs(~wool+tension, data=warpbreaks)
tension
wool L M H
A 9 9 9
B 9 9 9
gmodels
个包有一个函数CrossTable
,它提供的输出类似于SPSS或SAS的用户期望:
library(gmodels)
with(warpbreaks, CrossTable(wool, tension))
Cell Contents
|-------------------------|
| N |
| Chi-square contribution |
| N / Row Total |
| N / Col Total |
| N / Table Total |
|-------------------------|
Total Observations in Table: 54
| tension
wool | L | M | H | Row Total |
-------------|-----------|-----------|-----------|-----------|
A | 9 | 9 | 9 | 27 |
| 0.000 | 0.000 | 0.000 | |
| 0.333 | 0.333 | 0.333 | 0.500 |
| 0.500 | 0.500 | 0.500 | |
| 0.167 | 0.167 | 0.167 | |
-------------|-----------|-----------|-----------|-----------|
B | 9 | 9 | 9 | 27 |
| 0.000 | 0.000 | 0.000 | |
| 0.333 | 0.333 | 0.333 | 0.500 |
| 0.500 | 0.500 | 0.500 | |
| 0.167 | 0.167 | 0.167 | |
-------------|-----------|-----------|-----------|-----------|
Column Total | 18 | 18 | 18 | 54 |
| 0.333 | 0.333 | 0.333 | |
-------------|-----------|-----------|-----------|-----------|
答案 1 :(得分:10)
reshape
包应该可以解决问题。
> library(reshape)
> df <- data.frame(PLANT = c("Tragopogon_pratensis","Anthriscus_sylvestris","Anthriscus_sylvestris","Heracleum_sphondylium","Anthriscus_sylvestris","Anthriscus_sylvestris","Cerastium_holosteoides"),
ANIMAL= c("Propylea_quatuordecimpunctata","Rhagonycha_nigriventris","Sarcophaga_carnaria","Sarcophaga_carnaria","Sarcophaga_variegata","Sphaerophoria_interrupta_Gruppe","Sphaerophoria_interrupta_Gruppe"),
INTERACTIONS = c(1,3,2,1,4,3,1),
stringsAsFactors=FALSE)
> df <- melt(df,id.vars=c("PLANT","ANIMAL"))
> df <- cast(df,formula=PLANT~ANIMAL)
> df <- replace(df,is.na(df),0)
> df
PLANT Propylea_quatuordecimpunctata Rhagonycha_nigriventris
1 Anthriscus_sylvestris 0 3
2 Cerastium_holosteoides 0 0
3 Heracleum_sphondylium 0 0
4 Tragopogon_pratensis 1 0
Sarcophaga_carnaria Sarcophaga_variegata Sphaerophoria_interrupta_Gruppe
1 2 4 3
2 0 0 1
3 1 0 0
4 0 0 0
我还在弄清楚如何解决order
问题,有什么建议吗?
答案 2 :(得分:8)
我想指出,我们可以在不使用函数with
的情况下获得相同的结果:
R Base Package
# 3 options
table(warpbreaks[, 2:3])
table(warpbreaks[, c("wool", "tension")])
table(warpbreaks$wool, warpbreaks$tension, dnn = c("wool", "tension"))
tension
wool L M H
A 9 9 9
B 9 9 9
包gmodels:
library(gmodels)
# 2 options
CrossTable(warpbreaks$wool, warpbreaks$tension)
CrossTable(warpbreaks$wool, warpbreaks$tension, dnn = c("Wool", "Tension"))
Cell Contents
|-------------------------|
| N |
| Chi-square contribution |
| N / Row Total |
| N / Col Total |
| N / Table Total |
|-------------------------|
Total Observations in Table: 54
| warpbreaks$tension
warpbreaks$wool | L | M | H | Row Total |
----------------|-----------|-----------|-----------|-----------|
A | 9 | 9 | 9 | 27 |
| 0.000 | 0.000 | 0.000 | |
| 0.333 | 0.333 | 0.333 | 0.500 |
| 0.500 | 0.500 | 0.500 | |
| 0.167 | 0.167 | 0.167 | |
----------------|-----------|-----------|-----------|-----------|
B | 9 | 9 | 9 | 27 |
| 0.000 | 0.000 | 0.000 | |
| 0.333 | 0.333 | 0.333 | 0.500 |
| 0.500 | 0.500 | 0.500 | |
| 0.167 | 0.167 | 0.167 | |
----------------|-----------|-----------|-----------|-----------|
Column Total | 18 | 18 | 18 | 54 |
| 0.333 | 0.333 | 0.333 | |
----------------|-----------|-----------|-----------|-----------|
答案 3 :(得分:6)
基础R中的xtabs应该可以工作,例如:
dat <- data.frame(PLANT = c("p1", "p2", "p2", "p4", "p5", "p5", "p6"),
ANIMAL = c("a1", "a2", "a3", "a3", "a4", "a5", "a5"),
INTERACTIONS = c(1,3,2,1,4,3,1),
stringsAsFactors = FALSE)
(x2.table <- xtabs(dat$INTERACTIONS ~ dat$PLANT + dat$ANIMAL))
dat$ANIMAL
dat$PLANT a1 a2 a3 a4 a5
p1 1 0 0 0 0
p2 0 3 2 0 0
p4 0 0 1 0 0
p5 0 0 0 4 3
p6 0 0 0 0 1
chisq.test(x2.table, simulate.p.value = TRUE)
我认为应该相当容易地做你正在寻找的东西。我不确定它在效率方面如何扩展到10E5列联表,但这在统计上可能是一个单独的问题。
答案 4 :(得分:3)
只需使用&#34; dcast()
&#34;的reshape2
功能包:
ans = dcast( df, PLANT~ ANIMAL,value.var = "INTERACTIONS", fill = 0 )
这里&#34; PLANT&#34;将在左栏,&#34; ANIMALS&#34;在第一行,填写表格将使用&#34; INTERACTIONS&#34;和&#34; NULL&#34;将使用0
填充值。答案 5 :(得分:3)
使用dplyr / tidyr
:
df <- read.table(text='PLANT ANIMAL INTERACTIONS
Tragopogon_pratensis Propylea_quatuordecimpunctata 1
Anthriscus_sylvestris Rhagonycha_nigriventris 3
Anthriscus_sylvestris Sarcophaga_carnaria 2
Heracleum_sphondylium Sarcophaga_carnaria 1
Anthriscus_sylvestris Sarcophaga_variegata 4
Anthriscus_sylvestris Sphaerophoria_interrupta_Gruppe 3
Cerastium_holosteoides Sphaerophoria_interrupta_Gruppe 1', header=TRUE)
library(dplyr)
library(tidyr)
df %>% spread(ANIMAL, INTERACTIONS, fill=0)
# PLANT Propylea_quatuordecimpunctata Rhagonycha_nigriventris Sarcophaga_carnaria Sarcophaga_variegata Sphaerophoria_interrupta_Gruppe
# 1 Anthriscus_sylvestris 0 3 2 4 3
# 2 Cerastium_holosteoides 0 0 0 0 1
# 3 Heracleum_sphondylium 0 0 1 0 0
# 4 Tragopogon_pratensis 1 0 0 0 0