【问题标题】:Adding row to a dataframe将行添加到数据框
【发布时间】:2020-11-02 07:57:00
【问题描述】:

我有一个这样的 df:

x <- data.frame("Year" = c(1945,1945,1946,1946,1947,1947), "Age" = c(1,2,1,2,1,2), "Value" = c(4,5,4,5,4,6))

我想根据一些条件添加新行: 例如,我想添加与第一行具有相同“YEAR”和“AGE”的第二行,但 Value 是第一行的值 minis 1。

我想要这样的结果:

x <- data.frame("Year" = c(1945, 1945,1945,1945,1946,1946,1946,1946,1947,1947,1947,1947), "Age" = c(1,1,2,2,1,1,2,2,1,1,2,2), "Value" = c(4,3,5,4,4,3,5,4,4,3,5,4))

感谢您帮助初学者。

【问题讨论】:

  • 我不太了解您的情况-您能澄清一下吗?例如,为什么5 在您想要的输出中的第 3 行?
  • 你可以试试这个:value &lt;- data.frame(x$Year, x$Value-1, x$Age) 然后colnames(value) &lt;- c("Year", "Value", "Age") 最后p &lt;- full_join(x, value, by = c("Year", "Value", "Age"))value 使用您想要的值创建一个数据框。 colnames 更改列名以匹配原始名称。 full_join 按列名合并两个数据框。

标签: r rows


【解决方案1】:

你可以这样做:

#original df
x <- data.frame("Year" = c(1945,1945,1946,1946,1947,1947), "Age" = c(1,2,1,2,1,2),"Value" = c(4,5,4,5,4,6))

#replicate df with value minus 1
y <- data.frame(x[,c("Year", "Age")], Value = x[,"Value"] -1)

#combine
z <- rbind(x,y)
z[order(z$Year, z$Age),]

   Year Age Value
1  1945   1     4
7  1945   1     3
2  1945   2     5
8  1945   2     4
3  1946   1     4
9  1946   1     3
4  1946   2     5
10 1946   2     4
5  1947   1     4
11 1947   1     3
6  1947   2     6
12 1947   2     5

上面的代码当然可以缩短,例如直接更新数据框 x 时。

x <- rbind(x, data.frame(x[,c("Year", "Age")], Value = x[,"Value"] -1))

正如下面评论中所指出的,使用transform()within() 可以进一步缩短代码(并使其更具可读性)。

x <- rbind(x, transform(x, Value = Value - 1))
x <- rbind(x, within(x, Value <- Value - 1))

【讨论】:

    【解决方案2】:

    base 中,您可以将每行重复两次,并将回收的0:-1 添加到Value

    within(x[rep(1:nrow(x), each = 2), ], Value <- Value + 0:-1)
    

    它的tidyverse 版本是

    library(tidyverse)
    
    x %>%
      uncount(2) %>% 
      mutate(Value = Value + 0:-1)
    

    他们都给出了以下内容。输出已经排序好了,不用order()或者arrange()了。

       Year Age Value
    1  1945   1     4
    2  1945   1     3
    3  1945   2     5
    4  1945   2     4
    5  1946   1     4
    6  1946   1     3
    7  1946   2     5
    8  1946   2     4
    9  1947   1     4
    10 1947   1     3
    11 1947   2     6
    12 1947   2     5
    

    【讨论】:

      【解决方案3】:

      这行得通吗:

      library(dplyr)
      x %>% inner_join(x %>% select(1)) %>% group_by(Year, Age) %>% 
      mutate(Value = case_when(row_number() == 2 ~ Value - 1, TRUE ~ Value))
      Joining, by = "Year"
      # A tibble: 12 x 3
      # Groups:   Year, Age [6]
          Year   Age Value
         <dbl> <dbl> <dbl>
       1  1945     1     4
       2  1945     1     3
       3  1945     2     5
       4  1945     2     4
       5  1946     1     4
       6  1946     1     3
       7  1946     2     5
       8  1946     2     4
       9  1947     1     4
      10  1947     1     3
      11  1947     2     6
      12  1947     2     5
      

      使用的数据:

      x
        Year Age Value
      1 1945   1     4
      2 1945   2     5
      3 1946   1     4
      4 1946   2     5
      5 1947   1     4
      6 1947   2     6
      

      【讨论】:

        猜你喜欢
        • 2017-03-29
        • 2016-02-07
        • 2021-02-19
        • 2018-08-03
        • 1970-01-01
        • 1970-01-01
        • 2022-01-03
        • 1970-01-01
        • 2017-12-22
        相关资源
        最近更新 更多