我有一个包含几列类别协变量的数据框。我正在尝试生成n选择2个表,
table(df[[1]],df[[2]])
table(df[[1]],df[[3]])
...
table(df[[n-1]],df[[n]])
我尝试将外部用作outer(df,df,table)
,但我得到一个可以肯定的错误,因为它会使用单括号而不是双括号。
我也尝试使用combn(df,2)
,但是它丢失了因子名称。
我应该简单地使用循环吗?建议我反对这样做,而赞成向量化,但是如果它同样有效,那么就足够了。
我应该提到我也尝试过xtabs(~., df)
,但是我认为这不仅生成了表,而且还生成了边际意外事件表。
有关矢量化的任何帮助,否则这些功能将很有用
编辑:我设法使用xtabs并通过将ith和jth变量名称粘贴到嵌套的for循环中由“ +”分隔的公式中,从而使用as.formula做到了这一点。
答案 0 :(得分:1)
循环效率不高应该无关紧要,因为循环不会很大。但是,apply
函数家族既具有表达性又很方便,因此值得考虑。这样就不必为结果预先分配数据结构,并且避免了麻烦的双重循环。
我将用一个玩具数据集来说明,一次只一步。让我们创建一个数据框df
,其中包含三列,分别为“ x”,“ y”和“ z”:
> n <- 1:5; (df <- as.data.frame(cbind(x=n, y=n*10, z=n*100)))
x y z
1 1 10 100
2 2 20 200
3 3 30 300
4 4 40 400
5 5 50 500
df
可以很容易地产生combn
的一对不同名称对,如问题所示:
> combn(names(df), 2)
[,1] [,2] [,3]
[1,] "x" "x" "y"
[2,] "y" "z" "z"
您可以使用每一列来索引df
的列:
> apply(combn(names(df), 2), 2, function(i) df[i])
[[1]]
x y
1 1 10
2 2 20
3 3 30
4 4 40
5 5 50
[[2]]
x z
1 1 100
2 2 200
3 3 300
4 4 400
5 5 500
[[3]]
y z
1 10 100
2 20 200
3 30 300
4 40 400
5 50 500
结果是一个数据帧列表,每个数据帧都有适当命名的列。因此,您可以调用lapply
来生成表。这是完整的解决方案。它会产生一个表列表。
> lapply(apply(combn(names(df), 2), 2, function(i) df[i]), table)
[[1]]
y
x 10 20 30 40 50
1 1 0 0 0 0
2 0 1 0 0 0
3 0 0 1 0 0
4 0 0 0 1 0
5 0 0 0 0 1
[[2]]
z
x 100 200 300 400 500
1 1 0 0 0 0
2 0 1 0 0 0
3 0 0 1 0 0
4 0 0 0 1 0
5 0 0 0 0 1
[[3]]
z
y 100 200 300 400 500
10 1 0 0 0 0
20 0 1 0 0 0
30 0 0 1 0 0
40 0 0 0 1 0
50 0 0 0 0 1
答案 1 :(得分:0)
通过使用Map功能,您可以使用FP魔术轻松完成此操作,
Map(function(n) table(a[[n[1]]], a[[n[2]]]), combn(colnames(a), 2, simplify = FALSE))