You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R的DataFrame中找出各公司数值>0的首尾月份?

你给出的tibble数据如下:

> trial
# A tibble: 6 x 13
  Company `Jan-17` `Feb-17` `Mar-17` `Apr-17` `May-17` `Jun-17` `Jul-17` `Aug-17` `Sep-17`
  <chr>      <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>
1 A            83.       0.      33.      52.       0.      91.      61.       0.      40.
2 B             0.       0.       0.       0.       0.       0.       0.       0.       0.
3 C             5.      69.       0.      63.       6.      58.       0.       0.       0.
4 D            48.       0.       0.       0.       0.      74.      93.       3.      18.
5 E            39.       0.       0.       0.       0.       0.       0.       0.       0.
6 F             0.      90.       0.       0.       0.       0.       0.       0.       0.
# ... with 3 more variables: `Oct-17` <dbl>, `Nov-17` <dbl>, `Dec-17` <dbl>

针对你的需求,我先给你推荐更高效的tidyverse方案(特别适合处理数千行的大规模数据,比for循环效率高很多),之后再补充你问到的for循环实现方式:

一、更优的tidyverse解决方案

这个方法利用tidyr的宽转长功能和dplyr的分组聚合,代码简洁且性能出色,完全适配大数据场景:

首先加载必要的包:

library(dplyr)
library(tidyr)

然后执行以下步骤:

  1. 将宽格式数据转为长格式,把每个月份列拆成单独的行记录
  2. 过滤掉所有数值为0的无效行
  3. 按公司分组,提取每组的第一个和最后一个非零月份

代码如下:

result <- trial %>%
  pivot_longer(cols = -Company, names_to = "Month", values_to = "Value") %>%
  filter(Value > 0) %>%
  group_by(Company) %>%
  summarise(
    First_nonzero_month = first(Month),
    Last_nonzero_month = last(Month)
  )

补充:保留全0公司的处理

如果有些公司所有月份数值都是0(比如例子里的B公司),上面的代码会自动排除这些公司。如果你想保留它们并标记为NA,可以调整代码:

result <- trial %>%
  pivot_longer(cols = -Company, names_to = "Month", values_to = "Value") %>%
  group_by(Company) %>%
  summarise(
    First_nonzero_month = if(all(Value == 0)) NA else first(Month[Value > 0]),
    Last_nonzero_month = if(all(Value == 0)) NA else last(Month[Value > 0])
  )

二、for循环实现方式

虽然for循环在处理大数据时效率不如向量化操作,但如果你确实需要用for循环实现,也可以这样写:

首先初始化一个结果数据框,用来存储每个公司的计算结果:

# 获取所有公司名称
companies <- trial$Company
# 创建空的结果数据框
result_loop <- data.frame(
  Company = companies,
  First_nonzero_month = NA_character_,
  Last_nonzero_month = NA_character_,
  stringsAsFactors = FALSE
)

# 获取所有月份列的名称
month_cols <- colnames(trial)[-1]

# 遍历每个公司
for(i in seq_along(companies)){
  # 提取当前公司的所有月份数值
  values <- trial[i, -1] %>% unlist()
  # 找到数值>0的列索引
  nonzero_indices <- which(values > 0)
  
  if(length(nonzero_indices) > 0){
    # 赋值第一个非零月份
    result_loop$First_nonzero_month[i] <- month_cols[min(nonzero_indices)]
    # 赋值最后一个非零月份
    result_loop$Last_nonzero_month[i] <- month_cols[max(nonzero_indices)]
  }
  # 没有非零值的公司保持NA,无需额外处理
}

代码解释

  • 先提前提取公司列表和月份列名,避免在循环中重复计算,提升一点效率
  • 每次循环取出当前公司的所有数值,用which()定位非零值的位置
  • 如果存在非零值,就取最小和最大索引对应的月份名;如果没有,保持初始的NA

内容的提问来源于stack exchange,提问作者Anirudh Murali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:16:50