【问题标题】:how to perform row wise operation on different column in r如何对r中的不同列执行逐行操作
【发布时间】:2017-06-30 17:36:00
【问题描述】:

我在 r 中有以下数据框

 count1      count2      count3
   0           12          11 
  12           13          44
  22           32          13

我想计算count2,count1和count3和count2之间的距离,如下所示

 sqrt(abs(count2-count1) + abs(count3-count2))

到数据帧的每一行。我想要的数据框如下

 count1      count2      count3     distance
   0           12          11       sqrt(abs(12-0)+abs(12-11))
  12           13          44       sqrt(abs(13-12)+abs(44-13))
  22           32          13       sqrt(abs(32-22)+abs(13-32))

我的做法是使用 for 循环

 for(i in 1:nrow(df)){
    df$distance[i] <- sqrt(abs(df$count1[i] - df$count2[i]) + abs(df$count2[i] - df$count3[i]))
   }

上面有没有更好的方法?

【问题讨论】:

  • 您不需要 for 循环,因为此操作在 R 中是矢量化的。通过删除大约 15 个字符来修改您的内部行的简单单行符就可以了:df$distance &lt;- sqrt(abs(df$count1 - df$count2) + abs(df$count2 - df$count3))。 akrun 的回答使这使用with 变得更简单。根本不需要任何包。

标签: r


【解决方案1】:

我想dplyr 包是解决这个问题的方法:

df <- data.frame(count1 = sample(1:100,10),count2 = sample(1:100,10),count3 = sample(1:100,10))


> df %>% mutate(distance=sqrt(abs(count2-count1) + abs(count3-count2)))
   count1 count2 count3 distance
1      79     59     54 5.000000
2      70     18     22 7.483315
3      31     13     57 7.874008
4      54     49     53 3.000000
5      94     67     77 6.082763
6      51     74     21 8.717798
7      33      4     24 7.000000
8      90     79     78 3.464102
9       6     64     98 9.591663
10     22     68     28 9.273618

【讨论】:

    【解决方案2】:
    df$distance = apply(df, 1,
                        function(x) sqrt(abs(x[2] - x[1]) + abs(x[3] - x[2])))
    df
    

    【讨论】:

      【解决方案3】:

      我们可以使用base R

      df$distance <- with(df, sqrt(abs(count2 - count1) + abs(count3 - count2)))
      

      或与rowSums 来自base R

      df$distance <-  sqrt(rowSums(abs(df[-1] - df[-length(df)])))
      

      数据

      df <- structure(list(count1 = c(0L, 12L, 22L), count2 = c(12L, 13L, 
      32L), count3 = c(11L, 44L, 13L)), .Names = c("count1", "count2", 
      "count3"), class = "data.frame", row.names = c(NA, -3L))
      

      【讨论】:

        【解决方案4】:

        您也可以使用data.table 包:

        library(data.table)
        
        y <- data.table(count1 = c(0,12,22), count2 = c(12,13,32), count3 = c(11,44,13))
        
        y[, distance := sqrt(abs(count2 - count1) + abs(count3 - count2))]
        

        结果:

        > y
           count1 count2 count3 distance
        1:      0     12     11 3.605551
        2:     12     13     44 5.656854
        3:     22     32     13 5.385165
        

        【讨论】:

          【解决方案5】:

          使用 dplyr 包

          现在几乎是标准

          这是一个使用 iris 数据的工作示例(使用 dput(namedataset) 共享您的数据库)

          library(dplyr)
          
          iris[1:3] %>% mutate(res=sqrt(abs(Sepal.Length-Sepal.Width)))
          

          【讨论】:

          • 对不起,我在回答时根本没有回答
          猜你喜欢
          • 1970-01-01
          • 2019-09-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-08-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多