2

我需要制作一百万张表,所以我不是在循环,而是在尝试使我的代码功能化。但是,我无法使功能正常工作,我也不知道为什么。以下是一些可以使用的示例数据:

  # example data:
set.seed(1)
dframe <- data.frame(time=c(rep("before", 6), rep("after", 4)), 
                     Quest1=sample(0:5, 10, replace=TRUE))
dframe
  # result: 
     time Quest1
1  before      1
2  before      2
3  before      3
4  before      5
5  before      1
6  before      5
7   after      5
8   after      3
9   after      3
10  after      0

这是我尝试过的代码:

  # works:
tab1 <- prop.table(with(dframe, table(time, factor(Quest1, c(0:5)))), 1)
tab1
  # result:
time         0     1     2     3     4     5
after  0.250 0.000 0.000 0.500 0.000 0.250
before 0.000 0.333 0.167 0.167 0.000 0.333

  # doesn't work:  
makeTab = function(data, rowVar, colVar) {
  prop.table(with(data, table(rowVar, factor(colVar, c(0:5)))), 1)
}
tab1 <- makeTab(dframe, time, Quest1)
  # result:
Error in factor(colVar, c(0:5)) : object 'Quest1' not found

  # works:
tab1 <- prop.table(table(dframe$time, factor(dframe$Quest1, c(0:5))), 1)
tab1
  # (result same as above)

  # doesn't work:  
makeTab = function(data, rowVar, colVar) {
  prop.table(table(data$rowVar, factor(data$colVar, c(0:5))), 1)
}
tab1 <- makeTab(dframe, time, Quest1)
tab1
  # result:
     0 1 2 3 4 5

请注意,循环确实有效:

  # works:  
tab <- list()
for(i in 1:1){
  tab[[i]] <- prop.table(table(dframe$time, factor(dframe[,i+1], c(0:5))), 1)
}
tab
  # result:
[[1]]

             0     1     2     3     4     5
  after  0.250 0.000 0.000 0.500 0.000 0.250
  before 0.000 0.333 0.167 0.167 0.000 0.333
4

3 回答 3

4

你需要使用get. 如果您包装rowVarcolVar放入,您的第一个示例将起作用get

makeTab = function(data, rowVar, colVar) {
  prop.table(with(data, table(get(rowVar), factor(get(colVar), c(0:5)))), 1)
}
tab1=makeTab(dframe, 'time', 'Quest1')

tab1

#                 0         1         2         3         4         5
#  after  0.2500000 0.0000000 0.0000000 0.5000000 0.0000000 0.2500000
#  before 0.0000000 0.3333333 0.1666667 0.1666667 0.0000000 0.3333333

或者在您的第二个示例中使用[而不是$. 当前,您要的是列rowVar而不是其值:

makeTab = function(data, rowVar, colVar) {
  prop.table(table(data[, rowVar], factor(data[, colVar], c(0:5))), 1)
}

另请注意,我传递的是列名 ( 'Quest1') 的字符串,而不是名为Quest1.


正如 Joran 所提到的,第二种选择可能更可取,因为使用get通常会产生无法预料的后果!

于 2013-07-11T18:29:04.627 回答
4

因为您提到了数百万个表,并且我担心您打算使用循环(例如,lapply)的循环构造,所以这里是做两个(或更多)列的替代方法:

set.seed(1)
dframe <- data.frame(time=c(rep("before", 6), rep("after", 4)), 
                     Quest1=sample(0:5, 10, replace=TRUE),
                     Quest2=sample(0:5, 10, replace=TRUE))

library(reshape2)
dframe <- melt(dframe,id.vars="time")

tab <- prop.table(table(dframe$time,factor(dframe$value, c(0:5)),dframe$variable), 
                  c(1,3))

# , ,  = Quest1
# 
# 
#                0         1         2         3         4         5
# after  0.2500000 0.0000000 0.0000000 0.5000000 0.0000000 0.2500000
# before 0.0000000 0.3333333 0.1666667 0.1666667 0.0000000 0.3333333
# 
# , ,  = Quest2
# 
# 
#                0         1         2         3         4         5
# after  0.0000000 0.0000000 0.2500000 0.0000000 0.5000000 0.2500000
# before 0.0000000 0.3333333 0.3333333 0.0000000 0.3333333 0.0000000
于 2013-07-11T18:57:49.383 回答
3

如果你想坚持你的功能设计,你也可以使用eval

makeTab = function(data, rowVar, colVar)
    prop.table(with(data, table(eval(rowVar), factor(eval(colVar), 0:5))), 1)

makeTab(dframe, time, Quest1)
##              0       1       2       3       4       5
## after  0.25000 0.00000 0.00000 0.50000 0.00000 0.25000
## before 0.00000 0.33333 0.16667 0.16667 0.00000 0.33333
于 2013-07-11T18:36:46.377 回答