【问题标题】:Add a column that count number of rows until the first 1, by group in R在 R 中按组添加一列,计算行数直到第一个 1
【发布时间】:2021-10-08 15:56:29
【问题描述】:

我有以下数据集:

test_df=data.frame(Group=c(1,1,1,1,2,2),var1=c(1,0,0,1,1,1),var2=c(0,0,1,1,0,0),var3=c(0,1,0,0,0,1))

Group var1 var2 var3
1 1 0 0
1 0 0 1
1 0 1 0
1 1 1 0
2 1 0 0
2 1 0 1

我想为 var1-3 添加 3 列 (out1-3),按组计算直到第一个 1 的行数,

如下图:

Group var1 var2 var3 out1 out2 out3
1 1 0 0 1 3 2
1 0 0 1 1 3 2
1 0 1 0 1 3 2
1 1 1 0 1 3 2
2 1 0 0 1 0 2
2 1 0 1 1 0 2

我使用了这个 R 代码,我为我的 3 个变量重复了它,我的实际数据集不仅仅包含 3 列。 但它不起作用:

test_var1<-select(test_df,Group,var1 )%>% 
  group_by(Group) %>% 
  mutate(out1 = row_number()) %>% 
  filter(var1 != 0) %>% 
  slice(1)

【问题讨论】:

标签: r dataframe data-management


【解决方案1】:
df <- data.frame(Group=c(1,1,1,1,2,2),
                 var1=c(1,0,0,1,1,1),
                 var2=c(0,0,1,1,0,0),
                 var3=c(0,1,0,0,0,1))

这适用于任意数量的变量,只要结构与示例中的相同(即 Group + 许多 0 或 1 的变量)

df %>% 
  mutate(rownr = row_number()) %>%
  pivot_longer(-c(Group, rownr)) %>%
  group_by(Group, name) %>%
  mutate(out = cumsum(value != 1 & (cumsum(value) < 1)) + 1,
         out = ifelse(max(out) > n(), 0, max(out))) %>% 
  pivot_wider(names_from = c(name, name), values_from = c(value, out)) %>% 
  select(-rownr)

返回:

  Group value_var1 value_var2 value_var3 out_var1 out_var2 out_var3
  <dbl>      <dbl>      <dbl>      <dbl>    <dbl>    <dbl>    <dbl>
1     1          1          0          0        1        3        2
2     1          0          0          1        1        3        2
3     1          0          1          0        1        3        2
4     1          1          1          0        1        3        2
5     2          1          0          0        1        0        2
6     2          1          0          1        1        0        2

【讨论】:

    【解决方案2】:

    如果你只有 3 个“out”变量,那么你可以创建如下三行

    #1- Your dataset
    df=data.frame(Group=rep(1,4),var1=c(1,0,0,1),var2=c(0,0,1,1),var3=c(0,1,0,0))
    
    #2- Count the first row number with "1" value
    df$out1=min(rownames(df)[which(df$var1==1)])
    df$out2=min(rownames(df)[which(df$var2==1)])
    df$out3=min(rownames(df)[which(df$var3==1)])
    

    如果您有超过 3 列,那么最好创建一个循环,例如

    for(i in 1:3){
        df[paste("out",i,sep="")]=min(rownames(df)[which(df[,which(colnames(df)==paste("var",i,sep=""))]==1)])
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-09
      • 2022-07-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多