我需要将R data.frame对象转换为SpatialPointsDataFrame对象,以便对数据运行空间统计函数。但是,由于某些原因,将data.frame对象转换为SpatialPointsDataFrame会在转换后的对象上运行特定函数时出现意外行为。
在这个例子中,我尝试在生成的SpatialPointsDataFrame上运行head()函数 为什么函数head()在某些SpatialPointsDataFrame对象上失败?
以下是重现行为的代码。
示例1,没有错误:
#beginning of r code
#load S Classes and Methods for Spatial Data package "sp"
library(sp)
#Load an example dataset that contain geographic ccoordinates
data(meuse)
#check the structure of the data, it is a data.frame
str(meuse)
#>'data.frame': 155 obs. of 14 variables: ...
#with coordinates x,y
#Convert the data into a SpatialPointsDataFrame, by function coordinates()
coordinates(meuse) <- c("x", "y")
#check structure, seems ok
str(meuse)
#Check first rows of the data
head(meuse)
#It worked!
#Now create a small own dataset
testgeo <- as.data.frame(cbind(1:10,1:10,1:10))
#set colnames
colnames(testgeo) <- c("x", "y", "myvariable")
#convert to SpatialPointsDataFrame
coordinates(testgeo) <- c("x", "y")
#Seems ok
str(testgeo)
#But try running for instance head()
head(testgeo)
#Resulting output: Error in `[.data.frame`(x@data, i, j, ..., drop = FALSE) :
#undefined columns selected
#end of example code
我不理解的两个示例数据集之间存在一些差异。函数str()没有揭示差异?
为什么函数head()在数据集testgeo上失败?
为什么head()在添加更多列时起作用,10似乎是限制:
testgeo <- as.data.frame(cbind(1:10,1:10,1:10,1:10,1:10,1:10,1:10,1:10))
coordinates(testgeo) <- c("V1", "V2")
head(testgeo)
答案 0 :(得分:6)
head
没有特定的SpatialPoints/PolygonsDataFrames
方法,因此当您致电head(testgeo)
或head(meuse)
时,它会转到默认方法:
> getAnywhere("head.default")
A single object matching ‘head.default’ was found
It was found in the following places
registered S3 method for head from namespace utils
namespace:utils
with value
function (x, n = 6L, ...)
{
stopifnot(length(n) == 1L)
n <- if (n < 0L)
max(length(x) + n, 0L)
else min(n, length(x))
x[seq_len(n)]
}
<bytecode: 0x97dee18>
<environment: namespace:utils>
这样做会返回x[1:n]
,但是对于那些空间类,方括号索引就像列一样:
> meuse[1]
coordinates cadmium
1 (181072, 333611) 11.7
2 (181025, 333558) 8.6
3 (181165, 333537) 6.5
4 (181298, 333484) 2.6
5 (181307, 333330) 2.8
6 (181390, 333260) 3.0
7 (181165, 333370) 3.2
8 (181027, 333363) 2.8
9 (181060, 333231) 2.4
10 (181232, 333168) 1.6
> meuse[2]
coordinates copper
1 (181072, 333611) 85
2 (181025, 333558) 81
3 (181165, 333537) 68
4 (181298, 333484) 81
5 (181307, 333330) 48
6 (181390, 333260) 61
7 (181165, 333370) 31
8 (181027, 333363) 29
9 (181060, 333231) 37
10 (181232, 333168) 24
因此,当您执行head(meuse)
时,它会尝试meuse[1]
meuse[6]
,meuse
存在,因为testgeo
有很多列。
但head.SpatialPointsDataFrame
没有。所以它失败了。
真正的解决方法可能是写一个> head.SpatialPointsDataFrame = function(x,n=6,...){x[1:n,]}
:
> head(meuse)
coordinates cadmium copper lead zinc elev dist om ffreq soil
1 (181072, 333611) 11.7 85 299 1022 7.909 0.00135803 13.6 1 1
2 (181025, 333558) 8.6 81 277 1141 6.983 0.01222430 14.0 1 1
3 (181165, 333537) 6.5 68 199 640 7.800 0.10302900 13.0 1 1
4 (181298, 333484) 2.6 81 116 257 7.655 0.19009400 8.0 1 2
5 (181307, 333330) 2.8 48 117 269 7.480 0.27709000 8.7 1 2
6 (181390, 333260) 3.0 61 137 281 7.791 0.36406700 7.8 1 2
lime landuse dist.m
1 1 Ah 50
2 1 Ah 30
3 1 Ah 150
4 0 Ga 270
5 0 Ah 380
6 0 Ga 470
> head(testgeo)
coordinates myvariable
1 (1, 1) 1
2 (2, 2) 2
3 (3, 3) 3
4 (4, 4) 4
5 (5, 5) 5
6 (6, 6) 6
这样:
data.frame
这里真正的实际问题是空间类不会从{{1}}继承,所以它们的行为不像它们。
答案 1 :(得分:2)
head(meuse)
未向您提供数据集meuse
的前几行,但是它的前几列(6 +坐标列)。
您的数据集testgeo
只有1列,因此head(testgeo)
失败。但是head(testgeo,1)
有效。
head(testgeo,1)
coordinates myvariable
1 (1, 1) 1
2 (2, 2) 2
3 (3, 3) 3
4 (4, 4) 4
5 (5, 5) 5
6 (6, 6) 6
7 (7, 7) 7
8 (8, 8) 8
9 (9, 9) 9
10 (10, 10) 10
我不知道选择列而不是行的原因,但如果您想查看testgeo
的前几行,可以使用更传统的行:
testgeo[1:5, ]
coordinates myvariable
1 (1, 1) 1
2 (2, 2) 2
3 (3, 3) 3
4 (4, 4) 4
5 (5, 5) 5
答案 2 :(得分:0)
sp现在对所有head
个对象都有一个Spatial
方法,实现为
> sp:::head.Spatial
function (x, n = 6L, ...)
{
ix <- sign(n) * seq(abs(n))
x[ix, , drop = FALSE]
}
请注意,它还会处理否定的n