【问题标题】:Counting Frequencies Using (logical?) Expressions使用(逻辑?)表达式计算频率
【发布时间】:2024-01-20 08:03:01
【问题描述】:

我一直在从头开始自学 R,所以请多多包涵。我找到了多种计算观察值的方法,但是,我试图弄清楚如何使用(逻辑?)表达式计算频率。我有大量数据,大约有 100 万个观察值。 df 是这样设置的:

    Latitude    Longitude   ID  Year    Month   Day Value
66.16667    -10.16667   CPUELE25399 1979    1   7   0
66.16667    -10.16667   CPUELE25399 1979    1   8   0
66.16667    -10.16667   CPUELE25399 1979    1   9   0

有 154 个唯一 ID,同样有 154 个唯一纬度/经度。我专注于每个唯一 ID 所有值的前 1%。对于每个唯一 ID,我使用它们的关联值计算了第 99 个百分位数。我更进一步计算了每个 ID 在各个年份和月份的第 99 个百分位,即对于 1979 年的 CPUELE25399 for month=1,第 99 个百分位值为 3(3 是前 1% 的下限)

使用这些阈值:对于每个 ID、每年、每个月 - 我需要计算该值 >= ID 为第 99 个百分位的次数(每年每月)

我已经尝试了至少 100 种不同的方法,但我认为我从根本上误解了语法中的某些东西?这是让我走得最远的sn-p代码:

ddply(Total,
      c('Latitude','Longitude','ID','Year','Month'),
        function(x) c(Threshold=quantile(x$Value,probs=.99,na.rm=TRUE),
                      Frequency=nrow(x$Value>=quantile(x$Value,probs=.99,na.rm=TRUE))))

R 抛出一条警告消息说 >= 对因子没有用? 如果有人理解这个令人费解的信息,我将非常感谢您的帮助。

【问题讨论】:

  • class(x$Value) 类似“数字”或“整数”,还是“因子”?如果它是一个因素,那么当您读入它时,其中可能有一个字符串(-ish)值。如果它是一个因素并且您想按原样转换为数字,请执行x$Value = as.numeric(as.character(x$Value))
  • 另外,“对于每个 ID,对于每一年,对于每个月——我需要计算该值 >= ID 为第 99 个百分位的次数(每年每月)”—— > 这是否意味着您不需要按“每个纬度/经度”分开(这就是您的 ddply 似乎正在做的事情)。
  • 欢迎来到 SO。为了获得更快,更好的帮助,请提供您数据的玩具示例(请参阅?dput),以便有人可以加入。至少,str(Total) 是必要的,以确认怀疑Total$Value 确实是一个因素
  • 使用 str(Total) 后:唯一的因素是 ID 类别所有其他因素都是整数或数字类型据我了解 ddply('x','y'..) 中的参数是对变量进行分组并只提取所有具有与其关联的唯一 ID 的数据?对不起,我还不太了解白话,所以我什至不知道我是否使用了正确的词..

标签: r frequency


【解决方案1】:

使用这些阈值:对于每个 ID、每年、每个月 - 我需要计算该值 >= ID 为第 99 个百分位的次数(每年每月)

这是否意味着你想要

  1. 计算每个 ID 的第 99 个百分位(即不考虑月份年份等),然后
  2. 计算出超出此值的次数,但现在按月、年以及 ID 进行拆分?

(注意:您的示例代码按纬度/经度分组,但您的问题中没有提到这一点,所以我忽略它。如果您想添加它,只需将其作为分组变量添加到适当的位置)。

在这种情况下,您可以先使用ddply 计算每个 ID 的百分位数:

# calculate percentile for each ID
Total <- ddply(Total, .(ID), transform, Threshold=quantile(Value, probs=.99, na.rm=T))

现在您可以按(ID、月份和年份)分组以查看超出的次数:

Total <- ddply(Total, .(ID, Month, Year), summarize, Freq=sum(Value >= Threshold))

请注意,summarize 将返回一个数据帧,其行数与.(ID, Month, Year) 的列数一样多,即将删除所有纬度/经度列。如果您想保留它,请使用transform 而不是summarize,然后Freq 将针对每个(ID、Mon、Year)组合的所有不同(Lat、Lon)重复。


ddply 的注意事项:

  • 可以像你一样做.(ID, Month, Year)而不是c('ID', 'Month', 'Year')
  • 如果您只想添加额外的列,使用 summarizemutatetransform 之类的内容可以让您轻松地完成此操作,而无需在列名前面添加所有 Total$

【讨论】: