【问题标题】:How to add different values in a column based on another column如何根据另一列在列中添加不同的值
【发布时间】:2017-04-30 21:49:47
【问题描述】:

大家好,我有一个数据集的一部分:

# A tibble: 10 × 2
      id value
   <dbl> <dbl>
1      1     2
2      1     2
3      1     2
4      5     2
5      6     3
6      7     0
7      8     4
8      8     4
9      9     1
10     9     1

我想为同一 ID 的每个后续值添加“1”。例如。 “id 1”的第一个值是 2,而“id 1”的第二个值是 3,“id 1”的第三个值是 4。但是,那些只有 1 个 id (5,6,7) 的值保持不变是。所以本质上,前几个值看起来像这样:

# A tibble: 10 × 2
      id value
   <dbl> <dbl>
1      1     2
2      1     3
3      1     4
4      5     2
5      6     3
6      7     0
7      8     4
8      8     5
9      9     1
10     9     2

提前致谢!

乔伊

数据

structure(list(id = c(1, 1, 1, 5, 6, 7, 8, 8, 9, 9), value = c(2, 
2, 2, 2, 3, 0, 4, 4, 1, 1)), .Names = c("id", "value"), class = c("tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -10L))

预期输出:

structure(list(id = c(1, 1, 1, 5, 6, 7, 8, 8, 9, 9), value = c(2, 
3, 4, 2, 3, 0, 4, 5, 1, 2)), .Names = c("id", "value"), class = c("tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -10L))

【问题讨论】:

  • Ciao!欢迎来到 SO。首先你应该阅读here关于如何提出一个好问题;一个好的问题更有可能得到解决,你得到帮助。另一方面,阅读this 也是一件好事。它解释了如何在 R 中创建可重现的示例。通过提供一段数据、所需的输出和您已经尝试过的事情来帮助用户帮助您。
  • 我一定会调查的,谢谢。

标签: r dataframe row multiple-columns addition


【解决方案1】:

一个简单的data.table 解决方案是:

library(data.table)
dt<-as.data.table(df)
dt[, value2 := value + ((1:.N) - 1), by = id]

dt
#    id value value2
# 1:  1     2      2
# 2:  1     2      3
# 3:  1     2      4
# 4:  5     2      2
# 5:  6     3      3
# 6:  7     0      0
# 7:  8     4      4
# 8:  8     4      5
# 9:  9     1      1
#10:  9     1      2

另一种解决方案是使用 base R 和 rle:

df$value2 <- df$value + unlist(sapply(rle(df$id)$lengths, function(x) (1:x) - 1))

【讨论】:

  • 嗨,迈克,您的第一个解决方案运行良好。您介意解释解决方案中的语法吗?我的理解是:形成列 value2,它是 value 列与出现相同 id 的实例数之和,负 1 是为了使 id 的第一个实例保持不变。
  • 当然!我认为你说得对。对于每个by 组,加上1:length(group) 并减去1,以使原始值保持不变。因此,如果 by 组有 3 个观察值,它将向该组添加 c(1,2,3) - 1
  • 嗨,迈克,我还有最后一个问题。我的印象是“:=”,“==”和“
  • := 是特定于data.table 的语法,基本上创建/更新列。 == 是比较运算符,&lt;- 是赋值运算符。希望这是有道理的。您可以通过?`:=`?`==` 了解更多信息
  • 糟糕,我的意思是输入“=”而不是“==”。无论如何,非常感谢您的帮助,再次感谢!
【解决方案2】:

这是dplyr 的解决方案。考虑到如果数字不是渐进的(换句话说就是增加),这并不稳健,但我知道它们是这样的。如果不是,我们必须找到另一个解决方案。

df %>% group_by(id) %>%
    transmute(value = seq(from = min(value), by = 1, length.out = length(value)) )
Adding missing grouping variables: `id`
Source: local data frame [10 x 2]
Groups: id [6]

      id value
   <dbl> <dbl>
1      1     2
2      1     3
3      1     4
4      5     2
5      6     3
6      7     0
7      8     4
8      8     5
9      9     1
10     9     2

【讨论】:

  • 嗨,您的解决方案适用于我发布的小样本数据,但是它删除了所有其他变量名称,所以我只是切换了 transmute 并放入了 mutate 函数。感谢您的帮助!
【解决方案3】:

使用dplyr,您可以执行以下操作...

library(dplyr)
df2 <- df %>% group_by(id) %>% mutate(value=value+seq_along(id)-1)

【讨论】:

    【解决方案4】:

    或者我们可以使用base R

    df1$value <- with(df1, ave(value, id, FUN =seq_along)+value -1)
    df1$value
    #[1] 2 3 4 2 3 0 4 5 1 2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-15
      • 2021-03-23
      • 1970-01-01
      • 1970-01-01
      • 2018-08-10
      相关资源
      最近更新 更多