Home > Back-end >  How to do multiple arithmetic operations according to conditions between two datasets in R
How to do multiple arithmetic operations according to conditions between two datasets in R

Time:04-14

I have several datasets. The first one

lid=structure(list(x1 = 619490L, x2 = 10L, x3 = 0L, x4 = 6089230L, 
    x5 = 0L, x6 = -10L), class = "data.frame", row.names = c(NA, 
-1L))

second dataset

    lidar=structure(list(A = c(638238.76, 638238.76, 638239.29, 638235.39, 
638233.86, 638233.86, 638235.55, 638231.97, 638231.91, 638228.41
), B = c(6078001.09, 6078001.09, 6078001.15, 6078001.15, 6078001.07, 
6078001.07, 6078001.02, 6078001.08, 6078001.09, 6078001.01), 
    C = c(186.64, 186.59, 199.28, 189.37, 186.67, 186.67, 198.04, 
    200.03, 199.73, 192.14), gpstime = c(319805734.664265, 319805734.664265, 
    319805734.67875, 319805734.678768, 319805734.678777, 319805734.678777, 
    319805734.687338, 319805734.701928, 319805734.701928, 319805734.701945
    ), Intensity = c(13L, 99L, 5L, 2L, 20L, 189L, 2L, 11L, 90L, 
    1L), ReturnNumber = c(2L, 1L, 1L, 2L, 1L, 1L, 2L, 1L, 1L, 
    3L), NumberOfReturns = c(2L, 1L, 3L, 2L, 1L, 1L, 3L, 1L, 
    1L, 4L), ScanDirectionFlag = c(1L, 1L, 0L, 0L, 0L, 0L, 1L, 
    0L, 0L, 0L), EdgeOfFlightline = c(0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L), Classification = c(1L, 2L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L)), class = "data.frame", row.names = c(NA, 
-10L))

How to subtract the value for each row of the lidar dataset from lid dataset using the formula

(lidar$A-lid$x1)/lid$x3

then

(lidar$B-lid$x4)/lid$x6

So for first row will be result

(lidar$A-lid$x1)/lid$x3=1874,876(but everything after the comma is discarded)=1874(without,876)
 (lidar$B-lid$x4)/lid$x6=1122

also in lidar dataset for column lidar$C subtract the smallest value from the largest value. In this case lidar$c11-lidar$c1=5,5

so desired output for this will be

A   B   C   Intensity   ReturnNumber    NumberOfReturns row col subs(lidar$Cmax-lidar$Cmin)
638238.76   6078001.09  186.64  13  2   2   1874    1122    5,5
638238.76   6078001.09  186.59  99  1   1   1874    1122    5,5
638239.29   6078001.15  199.28  5   1   3   1874    1122    5,5
638235.39   6078001.15  189.37  2   2   2   1874    1122    5,5

the result of subtraction (lidar$Cmax-lidar$Cmin) for all rows is always the same. row and col this the result of this arithmetic

    (lidar$A-lid$x1)/lid$x3 (row)

then

    (lidar$B-lid$x4)/lid$x6 (col)

with the value after the comma, these values(row and col) are different, but we must remove the part after the comma, so they seem to be the same.

How can i get desired output according to such arithmetic operations. Any of your help is valuable.Thank you

CodePudding user response:

I'm not sure if this is what you mean

` lidar$row <- round((lidar$A-lid$x1)/lid$x3, 0)

lidar$col <- (lidar$B-lid$x4)/lid$x6

lidar$cdif <- max(lidar$C)-min(lidar$C)

`

CodePudding user response:

If I understand your purpose correctly, the main question is how to remove the part after comma, which is a decimal separator in your examples.

If that's true, one way of doing that is to split the number into two parts, one which comes before the comma and another one which comes after it, and then extract only the first part. In R you can do this by strsplit(). However, this function requires the input to be characters, not numerics. So, you need to coerce the numbers into characters, do the splitting, coerce the result back to numbers, and then extract its first element.

Here is an example of a function to implement the steps:

remove_after_comma <- function(num_with_comma){
    myfun <- function(num_with_comma) {
        num_with_comma|> 
        as.character() |> 
        strsplit("[,|.]") |>  
        unlist() |> 
        as.numeric() |> 
        getElement(1)
    }
    vapply(num_with_comma, myfun, FUN.VALUE = numeric(1))
}

Notes:

  • [,|.] is used to anticipate other systems that use . instead of , as the decimal separator.
  • vapply is used to make it possible to apply this function to a numeric vectors, such as a numeric column.

Check:

remove_after_comma(c(a = '1,5', b = '12,74'))
# a  b 
# 1 12 

(4:10)/3
#[1] 1.333333 1.666667 2.000000 2.333333 2.666667 3.000000 3.333333
remove_after_comma ((4:10)/3)
#[1] 1 1 2 2 2 3 3

Assuming that lid$x3 = 10L in your example:

(lidar$A-lid$x1)/lid$x3
#[1] 1874.876 1874.876 1874.929 1874.539 1874.386 1874.386 1874.555 1874.197 #1874.191 1873.841

remove_after_comma((lidar$A-lid$x1)/lid$x3) 
#[1] 1874 1874 1874 1874 1874 1874 1874 1874 1874 1873
  • Related