如何解决R中分层数据结构中的数据?

问题描述:

我创建了一个包含相同长度的两个数据列表(字符数组region和列表results)的列表。 (我试图管理data.frame中的数据,但将数据添加到data.frame似乎很复杂)。如何解决R中分层数据结构中的数据?

study = list(
    region = character(), 
    results = list() 
) 

study$region[1] = "Hamburg" 
study$results[[1]] = data.frame(month=c(1:5), maxTemp=c(-12, -1, 3, 10, 23)) 


study$region[2] = "Bremen" 
study$results[[2]] = data.frame(month=c(1:5), maxTemp=c(-9, -1, 6, 10, 21)) 

str(study) 

print("Maximum temperature of all study regions:") 
max(study$results[[1:2]]$maxTemp) 

我想找出所有地区的所有时间点的最高温度。我可以通过使用例如“ max(study$results[[1]]$maxTemp,但是当我试图解决所有地区max(study$results[[1:2]]$maxTemp我收到一个错误:

Error in study$results[[1:2]]$maxTemp :

$ operator is invalid for atomic vectors

哪里是我的错?如何解决在listlist中保存的几个data.frame的字段?什么是原子矢量?

[[只能返回一个元素。我以为[[会抛出,因为一个错误,而不是你所看到的,但阅读?"["错误告诉什么R 3与一个调用,如你不和解释的行为(从?"["):

Recursive (list-like) objects: ....

‘[[’ can be applied recursively to lists, so that if the single 
index ‘i’ is a vector of length ‘p’, ‘alist[[i]]’ is equivalent to 
‘alist[[i1]]...[[ip]]’ providing all but the final indexing 
results in a list. 

原因为你的错误是这样的:

> study$results[[c(1,2)]] 
[1] -12 -1 3 10 23 

这表明的是,R真的这样做

> study$results[[1]][[2]] 
[1] -12 -1 3 10 23 

即返回第一个数据帧的第二个分量(列),它是一个原子向量,因为R会丢弃空的维度。 $不能用于原子向量因此是错误的。

如果你想遍历是列表study$resultslapply()sapply()是你的朋友:

> lapply(study$results, function(y) max(y[, "maxTemp"], na.rm = TRUE)) 
[[1]] 
[1] 23 

[[2]] 
[1] 21 

> sapply(study$results, function(y) max(y[, "maxTemp"], na.rm = TRUE)) 
[1] 23 21 

如果您在$results上的组件名称弹出你会得到他们在输出过:

> names(study$results) <- study$region 
> lapply(study$results, function(y) max(y[, "maxTemp"], na.rm = TRUE)) 
$Hamburg 
[1] 23 

$Bremen 
[1] 21 

> sapply(study$results, function(y) max(y[, "maxTemp"], na.rm = TRUE)) 
Hamburg Bremen 
    23  21 

这是更容易使用,然后你不需要$region组件如果你愿意。

+0

工作的罚款。我不得不使用'y [['maxTemp“]]' – 2012-01-05 15:33:26

+0

来解决”maxTemp“列的问题。是否有一些具体的理由使用'y [,...]'而不是'y [...]'?什么是逗号? – hhh 2012-01-05 16:02:31

+0

@Sven这是另一种获得'maxTemp'组件的方法。使用无论你感觉什么是最简单的等。 – 2012-01-05 16:44:52

> max(data.frame(study$results[[2]]$maxTemp, study$result[[1]]$maxTemp)) 
[1] 23 

让我们来分析

> dput(data.frame(study$results[[2]]$maxTemp, study$result[[1]]$maxTemp)) 
structure(list(study.results..2...maxTemp = c(-9, -1, 6, 10, 
21), study.result..1...maxTemp = c(-12, -1, 3, 10, 23)), .Names = c("study.results..2...maxTemp", 
"study.result..1...maxTemp"), row.names = c(NA, -5L), class = "data.frame") 
# 
# NOT ATOMIC VECTOR HERE, look you can find there maxTemp --> it will work! 

比较,要

>dput(study$results[[1:2]]) 
c(-12, -1, 3, 10, 23)    # ATOMIC VECTOR! Cannot use `$` here... 

现在找到原子向量:

> Filter(is.atomic, study) 
$region 
[1] "Hamburg" "Bremen" 

而且"?Position(...)",你可能会喜欢这个问题here,解决标题。

你的数据结构太复杂了。您需要具有三列的单个数据帧:month,maxTempregion

n_months <- 5 
(study <- data.frame(
    month = rep.int(1:n_months, 2), 
    maxTemp = c(12, -1, 3, 10, 23, -9, -1, 6, 10, 21), 
    region = rep(c("Hamburg", "Bremen"), each = n_months) 
)) 

    month maxTemp region 
1  1  12 Hamburg 
2  2  -1 Hamburg 
3  3  3 Hamburg 
4  4  10 Hamburg 
5  5  23 Hamburg 
6  1  -9 Bremen 
7  2  -1 Bremen 
8  3  6 Bremen 
9  4  10 Bremen 
10  5  21 Bremen 

现在你所有地区的最高温度只是max(study$maxTemp)。没有困难的索引需要。


如果你真的必须坚持使用现有的数据结构,等效命令,以获得最高温度为

max(sapply(study, function(x) max(x$region$maxTemp))) 
+3

downvote有什么用?这个更好的数据结构使解决Sven的问题变得更容易。 – 2012-01-05 14:44:18

+1

我同意,投票人应该解释如何改善这个答案。同意,Richie的回答并不能解决OP的问题,但它确实提供了一个合理的选择。因此它不值得(如果可能的话)反对票。 – 2012-01-05 15:00:16