我正在使用从空间网格系统获得的数据,例如划分为等间距正方形(例如250平方米的单元格)的城市。每个单元格都拥有一个唯一的列和行号,以及有关该250平方米平方所包含区域的相应数字信息(即整个城市中每个单元的温度)。在整个网格部分(或示例城市)中,我有各种研究站点,我知道它们的位置(即每个站点位于哪个单元行和列中)。我有一个数据框,其中包含有关城市内所有单元格的信息,但我希望将其子集化为仅包含我的研究网站所在单元格的信息。我之前就此问题提出了一个问题Matching information from different dataframes and filtering out redundant columns'。这是一些示例代码:
###Dataframe showing cell values for my own study sites
Site <- as.data.frame(c("Site.A","Site.B","Site.C"))
Row <- as.data.frame(c(1,2,3))
Column <- as.data.frame(c(5,4,3))
df1 <- cbind(Site,Row, Column)
colnames(df1) <- c("Site","Row","Column")
###Dataframe showing information from ALL cells
eg1 <- rbind(c(1,2,3,4,5),c(5,4,3,2,1)) ##Cell rows and columns
eg2 <- as.data.frame(matrix(sample(0:50, 15*10, replace=TRUE), ncol=5)) ##Numerical information
df2 <- rbind(eg1,eg2)
rownames(df2)[1:2] <- c("Row","Column")
由此,我使用了之前问题的答案,这些答案对于示例数据非常有效。
output <- df2[, (df2['Row', ] %in% df1$Row) & (df2['Column', ] %in% df1$Column)]
names(output) <- df1$Site[mapply(function(r, c){which(r == df1$Row & c == df1$Column)}, output[1,], output[2,])]
但是,我无法将此应用于我自己的数据,也无法找出原因。
编辑:最初,我认为命名列存在问题(即&#39;名称&#39;功能)。但似乎“输出”可能会出现问题。代码行,其中df2中包含的列不应该是(即输出包含来自df2的列,其具有未在df1中指定的列和行号)。
我也尝试过:
output <- df2[, (df2['Row', ] == df1$Row) & (df2['Column', ] == df1$Column)]
但是当使用我自己的(看似可比较的)数据时,我无法从&#39; df1&#39;中指定的所有单元格获取信息。等效(虽然在上面的示例数据中再次正常工作)。如果我单独为每个研究地点进行研究,我可以获得自己的数据。
SiteA <- df2[, which(df2['Row', ] == 1) & (df2['Column', ] == 5)]
SiteB <- df2[, which(df2['Row', ] == 2) & (df2['Column', ] == 4)]
SiteC <- df2[, which(df2['Row', ] == 3) & (df2['Column', ] == 3)]
但我有1000个网站,并希望有一个更简洁的方式。我确信我保持了相同的结构,双重检查拼写和变量名称。是否有人能够揭露我可能做错的潜在事情?或者没有这种替代方法?
抱歉没有提供实际问题的示例代码(我希望我能够确定具体问题是什么,但在此之前,原始示例是我能做的最好的)!谢谢。
答案 0 :(得分:1)
我能看到的唯一明显问题是mapply
没有包裹unlist
。 mapply
会返回一个list
,这不是您之后用于子集目的的内容。所以,试试:
output <- df2[, (df2['Row', ] %in% df1$Row) & (df2['Column', ] %in% df1$Column)]
names(output) <- df1$Site[unlist(mapply(function(r, c){which(r == df1$Row & c == df1$Column)}, output[1,], output[2,]))]
编辑:
如果目标是抓取前两行与df1
中给定行的第二和第三个元素匹配的列,则可以尝试以下操作:
output_df <- Filter(function(x) !all(is.na(x)), data.frame(do.call(cbind,apply(df2, 2, function(x) {
##Create a condition vector for an if-statement or for subsetting
condition <- paste0(x[1:2], collapse = "") == apply(df1[,c('Row','Column')], 1, function(y) {
paste0(y,collapse = "")
})
##Return a column if it meets the condition (first 2 rows are matched in df1)
if(sum(condition) != 0) {
tempdf <- data.frame(x)
names(tempdf) <- df1[condition,]$Site[1]
tempdf
} else {
##If they are not matched, then return an empty column
data.frame(rep(NA,nrow(df2)))
}
}))))
这是一段相当简洁的代码,所以我希望以下解释有助于澄清一些事情:
这基本上遍历df2
中的每一列(apply(df2, 2, FUN)
),并检查df1
中每行的第2和第3个元素是否可以找到它的前2行。如果满足条件,则它以data.frame格式返回该列,其列名为Site
中匹配行中df1
的值;否则返回一个空列(包含NA
&#39; s)。然后将这些列与do.call
和cbind
绑定在一起,然后强制转换为data.frame。最后,我们使用Filter
函数删除值为NA
的列。
所有这些都应该提供以下内容:
Site.A Site.B Site.C
1 2 3
5 4 3
40 42 33
13 47 25
23 0 34
2 41 17
10 29 38
43 27 8
31 1 25
31 40 31
34 12 43
43 30 46
46 49 25
45 7 17
2 13 38
28 12 12
16 19 15
39 28 30
41 24 30
10 20 42
11 4 8
33 40 41
34 26 48
2 29 13
38 0 27
38 34 13
30 29 28
47 2 49
22 10 49
45 37 30
29 31 4
25 24 31
我希望这会有所帮助。