如何从数据框创建表

时间:2016-01-16 01:21:23

标签: r dataframe

以下是我拥有的数据框

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

任何建议都表示赞赏!

2 个答案:

答案 0 :(得分:3)

我们可以transform数据集创建另一个包含after 1970before 1970值的列。这可以通过首先创建逻辑向量(col1 <= 1970),向其中添加1以使TRUE变为2并将FALSE变为1来完成。将其用作数字索引以将值更改为after 1970before 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 ,它将行和/或列总数添加到计数或值表中(但是一旦转换为计数或值,这显然不是很有趣)的比例。)