以下是我拥有的数据框
col1<-c(1960,1960,1965,1986,1960
,1969,1960,1993,1983,1924,
1960,1993,1960,1972
,1960,1969)
col2<-c ("a", "c","a","b", "a", "c",
"b","a", "b","a", "b", "a",
"c","c","a","a" )
mydata<-data.frame(col1,col2)
我想创建一个双向表,分别计算1970年之前和1970年之后每个类别(a,b和c)的比例。
所需的输出应为:
year a b c
before 1970 0.545 0.181 0.272
after 1970 0.4 0.4 0.2
任何建议都表示赞赏!
答案 0 :(得分:3)
我们可以transform
数据集创建另一个包含after 1970
和before 1970
值的列。这可以通过首先创建逻辑向量(col1 <= 1970
),向其中添加1以使TRUE
变为2并将FALSE
变为1来完成。将其用作数字索引以将值更改为after 1970
和before 1970
。然后,我们使用table
获取列子集(&#39; col2&#39;和#39; col3&#39;)的频率。最后,可以使用prop.table
并将MARGIN
指定为1来获取按行的比例。
prop.table(table(transform(mydata, col3=c("after 1970",
"before 1970")[(col1<=1970)+1L])[3:2]), 1)
# col2
# col3 a b c
# after 1970 0.4000000 0.4000000 0.2000000
# before 1970 0.5454545 0.1818182 0.2727273
或data.table
library(data.table)
#convert the 'data.frame' to 'data.table' (`setDT(mydata)`)
#create the "year" column based on 'col1' values
setDT(mydata)[col1<=1970, year:= "before 1970"
][is.na(year), year:= "after 1970"]
#we can use `dcast` to change from long to wide format
dcast(mydata, year~col2, length)[, .SD/sum(unlist(.SD)) , year]
# year a b c
#1: after 1970 0.4000000 0.4000000 0.2000000
#2: before 1970 0.5454545 0.1818182 0.2727273
或dplyr/tidyr
library(dplyr)
library(tidyr)
mydata %>%
mutate(year= ifelse(col1 <= 1970, "before 1970", "after 1970")) %>%
group_by(year) %>%
mutate(n1=n()) %>%
group_by(col2,n1, add=TRUE) %>%
tally() %>%
ungroup() %>%
mutate(n=n/n1) %>%
select(-n1) %>%
spread(col2,n)
答案 1 :(得分:2)
我通常会发现应该bundle install
prop.table的结果:
round
如果您标记表格尺寸,您可能需要引用一些hte名称,如果它们中包含运算符:
> with( mydata, round( prop.table(table(col1 <= 1970, col2)), 3))
col2
a b c
FALSE 0.125 0.125 0.062
TRUE 0.375 0.125 0.188
修复将FALSE标记为“1970年或之前”的语义错误:如果要修改行名和列名,请使用with( mydata, round( prop.table(table(`Year<=1970` = (col1 <= 1970), Column_2=col2)), 3))
Column_2
Year<=1970 a b c
FALSE 0.125 0.125 0.062
TRUE 0.375 0.125 0.188
。首先将结果分配给对象'temp',然后:
dimnames<-
如果指定了MARGIN, > dimnames(temp)[[1]] <- list('after 1970', '1970 or before')
> temp
Column_2
Year<=1970 a b c
after 1970 0.125 0.125 0.062
1970 or before 0.375 0.125 0.188
可以提供行或列比例。这里我们使用prop.table
作为行边距(并且在名称更改之前将交换具有索引反转的行):
margin=1
在操作类别中经常使用的另一个有用函数是tb2 <- with( mydata, round(
prop.table(table(`Period` = (col1 <= 1970), Column_2=col2), margin=1), 3))[2:1, ]
dimnames(tb2)[[1]] <- list('1970 or before', 'after 1970')
tb2
Column_2
Period a b c
1970 or before 0.545 0.182 0.273
after 1970 0.400 0.400 0.200
,它将行和/或列总数添加到计数或值表中(但是一旦转换为计数或值,这显然不是很有趣)的比例。)