【问题标题】:R Selecting column in a data frame by column in another data frameR在另一个数据框中逐列选择数据框中的列
【发布时间】:2012-11-26 14:20:29
【问题描述】:

我在尝试对我的数据进行子集化时遇到问题,也许你可以帮助我。我需要的是当该列值等于第二个数据框中的列的值时,按列对第一个数据框中的数据进行子集化。

以下是我正在使用的数据框:

> head(places)
  Zona   Poble     lat       lon      alt
1    1  Zorita 40.7353 -0.165748  691.867
2    1 Morella 40.6287 -0.113284  955.719
3    1 Forcall 40.6621 -0.209759  753.882
4    2 Benasal 40.3943 -0.126111  848.171
5    2    Cati 40.4532  0.060409  667.610
6    2  Fredes 40.7079  0.167981 1194.730

> head(data)
      date   time stat_id     lat     lon    tempc
1 20121122 000000       1 40.7353 -0.1657  7.98737
2 20121122 000000       2 40.6287 -0.1133  6.49903
3 20121122 000000       3 40.6621 -0.2098  7.72955
4 20121122 000000       4 40.3943 -0.1261  7.98837
5 20121122 000000       5 40.4532  0.0604 10.35480
6 20121122 000000       6 40.7079  0.1680  6.00769

如您所见,数据帧“地点”中的三个第一位置属于 Zona == 1,并与数据帧“数据”中的三个第一行共享纬度/经度。我想在 places.dat 上选择与 Zona == i 共享纬度/经度的数据行。

我正在尝试的 R 脚本是

datos=read.table("data.dat",header=T)
places=read.table("places.dat",header=T)

data=as.data.frame(datos)
place=as.data.frame(pobles)

data$time[data$time == 0] = "000000"

subset(data,data$lat == place$lat[place$Zona == 1])

因此,subset 将在 data.dat 中每次显示三行,但它只选择三个中的两个,如下所示

> subset(data,data$lat == place$lat[place$Zona == 1])
         date   time stat_id     lat     lon    tempc
1    20121122 000000       1 40.7353 -0.1657  7.98737
2    20121122 000000       2 40.6287 -0.1133  6.49903
385  20121122  30000       1 40.7353 -0.1657  7.00632
386  20121122  30000       2 40.6287 -0.1133  4.83684
769  20121122  60000       1 40.7353 -0.1657  6.55283
770  20121122  60000       2 40.6287 -0.1133  4.85467
1153 20121122  90000       1 40.7353 -0.1657  6.35216
1154 20121122  90000       2 40.6287 -0.1133  5.66342
1537 20121122 120000       1 40.7353 -0.1657 11.47750
1538 20121122 120000       2 40.6287 -0.1133 10.30310
1921 20121122 150000       1 40.7353 -0.1657 13.87090
1922 20121122 150000       2 40.6287 -0.1133 11.90640
2305 20121122 180000       1 40.7353 -0.1657 10.30840
2306 20121122 180000       2 40.6287 -0.1133  7.61322
2689 20121122 210000       1 40.7353 -0.1657  6.29745
2690 20121122 210000       2 40.6287 -0.1133  6.63173
3073 20121123 000000       1 40.7353 -0.1657  4.78633
3074 20121123 000000       2 40.6287 -0.1133  5.31070
3457 20121123  30000       1 40.7353 -0.1657  6.84001
3458 20121123  30000       2 40.6287 -0.1133  6.88369
3841 20121123  60000       1 40.7353 -0.1657  5.71790

我肯定遗漏了什么,你能帮我吗?任何想法或提示将不胜感激。

谢谢

数据文件在这里:

编辑 根据@A.R 的回答,我尝试使用此代码来选择数据,但不确定它是否只是正确的方式。

for(i in 1:128) {
  for(j in 1:2) {
    a=sqrt((place$lat[i]-datos$lat[j])^2+(place$lon[i]-datos$lon[j])^2)
    n=which.min(a)
    while(n <= 9344) {
      b=cbind(i,n,datos$tempc[n],place$Zona[i])
      n=n+128
    }
  }
}

得到:

> b
       i    n           
[1,] 128 9217 10.1198 30

它只给出最后一个 i 值的值,我想全部保存。当然这是一个基本的,但我无法弄清楚,请耐心等待,因为我不是一个有经验的 R 用户。再次感谢

【问题讨论】:

  • 不确定您要做什么,但也许您应该先合并()然后再设置子集?您是否还尝试匹配浮点数(纬度/经度)?参考hep.by/gnu/r-patched/r-faq/R-FAQ_82.html
  • 嗨@Sean,谢谢。我认为合并不是一个好主意,因为 places 有 128 行(位置),而 data.dat 有 128 个位置 x 72 小时。也许问题是浮点数

标签: r subset


【解决方案1】:

首先,您需要将 places lon 的小数四舍五入到 4 位。可能这就是您遇到问题的原因:

places=read.table("places.dat",header=T)
places=round(places$lon,digits=4)


datos[which((datos$lat==places$lat & datos$lon==places$lon) & places$Zona==1),]

这个条件的总分是 146 分。

编辑 1(根据 Sean 的评论)

在我的回答中,我假设在 一些地方,lat 是圆的,而 long 不是。

但正如 Sean 所指出的,比较浮点数并不是一个好主意。最好计算每个 places 点和 datos 点之间的距离,并选择距离最小的一个,低于最小距离(例如点之间距离的一半)在 datos) 中,作为匹配项。

编辑 2

试试这样的:

b=matrix(nrow=dim(places)[1],ncol=5)
a=c()
data.p=c()
n=c()
for(i in 1:dim(places)[1]) {
  for(j in 1:dim(data)[1]) {
    a[j]=sqrt((places$lat[i]-data$lat[j])^2+(places$lon[i]-data$lon[j])^2)
  }   
  data.p[i]=which.min(a)
  n[i]=min(a)
}
b=cbind(places=1:(dim(places)[1]),data=data.p,distance=n,tempc=data$tempc[data.p],Zona=places$Zona)

比做一些查询:

b[which(b[,3]<1),]
b[which(b[,3]<0.00001),]

【讨论】:

  • 我认为小数可能是问题所在。然后我必须将 lat 和 lon 小数四舍五入为 4 位数字,以便它们在子集之前具有相同的尺寸。我明天上班试试看。谢谢
  • 抱歉,即使在使用 round-refer R-FAQ “7.31 为什么 R 认为这些数字不相等?”之后比较两个浮点数是否相等也是一个非常糟糕的主意。 - 如果您坚持比较这些,为什么不转换为字符串,您不妨将 lat & long 组合成一个字符串...但要注意...
  • Sean 这在很大程度上取决于数据本身以及坐标的获取方式(包括它们的精度),以及用户将如何处理这种比较。我希望在同一个数据集(位置)中具有相同数量的十进制数的 lat 和 long,这不会发生,并且可以假设 lat 是四舍五入到 4 位而不是 long,等等
  • 也许我应该使用 dist() 来查找位置中的点与 datos 中的所有点之间的距离。然后我可以为带有 places$Zona 的 datos 分配一个新列,这就是我需要为每个 places$Zona 找到 datos$tempc 的最大值/最小值(Zona 在西班牙语中的意思是区域)。这是我第一次尝试在 R 中计算距离,dist() 是正确的命令吗?
  • 你可以做的是对places中的每个i点和datos中的所有j点计算距离: sqrt((places$lat[i]-datos$lat[j])^2+ (地方$lon[i]-datos$lon[j]))。这意味着对于每个 i,您将拥有一个具有相同 datos 长度的距离列表。之后您需要创建一个最小距离阈值以避免在没有近邻的情况下选择距离太远的点。我不确定 dist() 是否能够在这里做你需要的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-06
  • 2016-02-14
  • 1970-01-01
相关资源
最近更新 更多