2012-12-06 68 views
2

我有一个data.frame与字符数据,我想最终与矩阵具有相同的列标题,但计数为每个值。到目前为止,我可以得到我想要的维度的空矩阵,但是当我尝试用计数填充myMatrix时,它不起作用。矩阵分配在lapply中失败

myData <- data.frame(a=LETTERS[5:8], b=LETTERS[6:9], c=rep(LETTERS[5:6],2), d=rep(LETTERS[7],4)) 
# a b c d 
# 1 E F E G 
# 2 F G F G 
# 3 G H E G 
# 4 H I F G 
myValues <- sort(unique(unlist(myData))) # E F G H I 
myList <- lapply(myData, table) 
myMatrix <- matrix(nrow=length(myValues), ncol=length(myList), dimnames=list(myValues,names(myList))) 
# a b c d 
# E NA NA NA NA 
# F NA NA NA NA 
# G NA NA NA NA 
# H NA NA NA NA 
# I NA NA NA NA 

到目前为止好。这是没有做什么,我期待的部分:

lapply(seq_along(myList), function(i) {myMatrix[names(myList[[i]]),names(myList[i])] <- myList[[i]]}) 

它返回正确的价值观,但myMatrix还是满的NAS。奇怪的是,这一个工程:

myMatrix[names(myList[[2]]),names(myList[2])] <- myList[[2]] 
# a b c d 
# E NA NA NA NA 
# F NA 1 NA NA 
# G NA 1 NA NA 
# H NA 1 NA NA 
# I NA 1 NA NA 

为什么是分配给myMatrix失败中lapply以及如何我可以得到它的工作(没有for循环)?

+2

你得到你想要的东西,如果你更换'''<-'''第二'''lapply'''与'''<< - ' ''。见''?“<< - ”'''。这是否是一个好主意是一个不同的问题。 – orizon

回答

2

@orizo​​n是为什么,你预计你的lapply使用不正确的工作。您必须将<-替换为<<-才能正常工作,但一般认为*apply函数具有这种副作用是不好的做法。

相反,你可以使用

sapply(lapply(myData, factor, unique(unlist(myData))), table) 

# a b c d 
# E 1 0 2 0 
# F 1 1 2 0 
# G 1 1 0 4 
# H 1 1 0 0 
# I 0 1 0 0 
5

这里有一个方法,将返回一个data.frame

# create table, convert to data.frames then give appropriate column names 
myList <- Map(setNames, lapply(lapply(myData, table), data.frame), Map(c, 'Var', names(myList))) 
# merge recursively 
Reduce(function(...) merge(..., by = 'Var', all = T), myList) 
    Var a b c d 
1 E 1 NA 2 NA 
2 F 1 1 2 NA 
3 G 1 1 NA 4 
4 H 1 1 NA NA 
5 I NA 1 NA NA 
+0

真的很不错的答案;没有足够的人在R中使用Map/Reduce/Filter函数:) – RyanGrannell

+0

upvote,但我接受@ flodel的答案,因为它更接近我所要求的(Var值为rownames的矩阵,而不是DF中的单独列)。微不足道,我知道,但我必须选择一个... – drammock

1

这里是另一种版本,这可能是不必要的复杂,但将返回其他的每个值的计数的矩阵。

t(
    sapply(
    as.character(unique(unlist(myData))), 
    function(x) 
     lapply(myData,function(y) sum(y==x)) 
     ) 
) 

结果:

a b c d 
E 1 0 2 0 
F 1 1 2 0 
G 1 1 0 4 
H 1 1 0 0 
I 0 1 0 0