【问题标题】:Manipulate rows of a data frame with specific variables per row使用每行特定变量操作数据框的行
【发布时间】:2020-01-25 12:56:06
【问题描述】:

我正在尝试通过唯一的采样区域来标准化不同列中的鱼数。

我有以下简化的数据集:

Year <- c(1990:2019) 
Location_nr <- c(1:30)
df <- data.frame(Year,Location_nr)
df$Sample_surface <- sample(10, size = nrow(df), replace = TRUE)
df$Fish1 <- sample(0:500, size = nrow(df), replace = TRUE)
df$Fish2 <- sample(0:500, size = nrow(df), replace = TRUE)
df$Fish3 <- sample(0:500, size = nrow(df), replace = TRUE)
df$Fish4 <- sample(0:500, size = nrow(df), replace = TRUE)

我想通过以下方式标准化每行的鱼数(列:Fish1、Fish2、Fish3 和 Fish4): (/"Sample_surface")/100

我已经被这个问题困扰了一天多。我真诚地希望有人可以帮助我。非常感谢!

【问题讨论】:

    标签: r database dataframe multiplication


    【解决方案1】:

    我们可以使用sweep 来应用对应Sample_surface 所在行的所有“Fish”列。

    cols<- grep('Fish', names(df))
    sweep(df[cols], 1, df$Sample_surface, `/`)/100
    
    head(df)
    #  Year Location_nr Sample_surface  Fish1 Fish2 Fish3 Fish4
    #1 1990           1              3 1.0967 0.050 1.410 1.530
    #2 1991           2              3 0.0733 0.383 1.223 0.703
    #3 1992           3             10 0.4100 0.093 0.285 0.173
    #4 1993           4              2 2.2150 1.305 1.975 1.360
    #5 1994           5              6 0.5133 0.390 0.263 0.742
    #6 1995           6              5 0.2680 0.910 0.240 0.602
    

    或者我们可以使用apply row-wise

    df[-c(1:3)] <- t(apply(df[-c(1:2)], 1, function(x) x[-1]/x[1]/100))
    

    数据

    set.seed(123)
    Year <- c(1990:2019) 
    Location_nr <- c(1:30)
    df <- data.frame(Year,Location_nr)
    df$Sample_surface <- sample(10, size = nrow(df), replace = TRUE)
    df$Fish1 <- sample(0:500, size = nrow(df), replace = TRUE)
    df$Fish2 <- sample(0:500, size = nrow(df), replace = TRUE)
    df$Fish3 <- sample(0:500, size = nrow(df), replace = TRUE)
    df$Fish4 <- sample(0:500, size = nrow(df), replace = TRUE)
    

    【讨论】:

      【解决方案2】:

      另一种选择是使用dplyrtidyr。在大多数情况下,建议以整齐的格式操作数据。

      df %>%
        pivot_longer(-c(Year:Sample_surface), names_to = 'Fish', values_to = 'Value') %>%
        mutate(Value = Value / Sample_surface / 100) %>%
        pivot_wider(names_from = Fish, values_from = Value)
      

      cbind(df %>% select(-starts_with('Fish')),
            df %>% select(starts_with('Fish')) / df$Sample_surface / 100)
      

      【讨论】:

        【解决方案3】:

        我们可以用矢量化的方式做到这一点

        cols<- grep('Fish', names(df))
        df[cols] <- (df[cols]/df$Sample_surface)/100
        head(df)
        #  Year Location_nr Sample_surface      Fish1     Fish2     Fish3     Fish4
        #1 1990           1              3 1.09666667 0.0500000 1.4100000 1.5300000
        #2 1991           2              3 0.07333333 0.3833333 1.2233333 0.7033333
        #3 1992           3             10 0.41000000 0.0930000 0.2850000 0.1730000
        #4 1993           4              2 2.21500000 1.3050000 1.9750000 1.3600000
        #5 1994           5              6 0.51333333 0.3900000 0.2633333 0.7416667
        #6 1995           6              5 0.26800000 0.9100000 0.2400000 0.6020000
        

        数据

        set.seed(123)
        Year <- c(1990:2019) 
        Location_nr <- c(1:30)
        df <- data.frame(Year,Location_nr)
        df$Sample_surface <- sample(10, size = nrow(df), replace = TRUE)
        df$Fish1 <- sample(0:500, size = nrow(df), replace = TRUE)
        df$Fish2 <- sample(0:500, size = nrow(df), replace = TRUE)
        df$Fish3 <- sample(0:500, size = nrow(df), replace = TRUE)
        df$Fish4 <- sample(0:500, size = nrow(df), replace = TRUE)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-04
          • 1970-01-01
          • 1970-01-01
          • 2017-11-30
          相关资源
          最近更新 更多