【问题标题】:How to subtract a row from another row in R?如何从R中的另一行中减去一行?
【发布时间】:2020-10-18 07:51:53
【问题描述】:

我是 R 的新手,并试图通过使用最新的 gapminder dataset(即从另一行减去一行)来 subtractcountry value 多年来 from another country

数据集

gapminder_new %>% 
  filter(country == c("India","Bangladesh"))

########## output ############

country 1960 1961 1962 1963   1964 1965  1966  1967
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>

Bangladesh  372 384 394 381 411 405 402 382 
India       330 336 339 352 370 353 345 365

我已经尝试了许多不同的组合,包括底座和管道,但都没有成功。

初始尝试失败

gapminder_new %>% 
  filter(country == c("India","Bangladesh")) %>% 
  .[country == "India",] - .[country == "Bangladesh",]

###################

gapminder_new %>% 
  filter(country == c("India","Bangladesh")) %>% 
  mutate(Diff_result = (. %>% filter(country == "India") ) - (. %>% filter(country == "Bangladesh"))  )

###################

gapminder_new[country == "India",] - gapminder_new[country == "Bangladesh",]

在这之后,我意识到这可能是一个问题,因为国家名称不能被减去,因为它们是字符,所以我应该从减法中消除它们并仅将它们用作行索引 就像在 python 中一样。

所以我尝试了下面的代码,但即使这样也不起作用:

按行索引减法

# setting a row index
rownames(gapminder_new) <- gapminder_new$country

# subtracting only numerical col using row index
gapminder_new["India", 2: ncol(gapminder_new)] - gapminder_new["Bangladesh", 2: ncol(gapminder_new)]

如何在基础 R 和使用管道中解决此问题???

每天我都会在 R 中遇到 10 种不同的数据操作任务。在某个地方我们需要 pull(),在某个地方只能选择 .[[]] 而不是在其他地方。所有这些规则在哪里定义?

我不知道为什么 R 的选择如此复杂,从基础 R 到管道,从单个 ML 包到插入符号到 tidymodel 再到许多其他东西。现在我真的觉得 Python 比 R 更简单、更容易学习,而且学习时间也很短。

(更新:这是我最终使用的并且还在答案中发布了详细信息)

#convert to data frame
gapminder_new <- as.data.frame(gapminder_new)

# set country row index
rownames(gapminder_new) <- gapminder_new$country

# subtracting only numerical col using row index
gapminder_new["India", 2: ncol(gapminder_new)] - gapminder_new["Bangladesh", 2: ncol(gapminder_new)]

【问题讨论】:

    标签: r tidyverse


    【解决方案1】:

    这是你要找的东西吗:

    > gapminder_new %>% select(-1) %>% mutate(across(everything(), ~lead(.x) - (.x))) %>% na.omit()
    # A tibble: 1 x 8
      `1960` `1961` `1962` `1963` `1964` `1965` `1966` `1967`
       <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
    1    -42    -48    -55    -29    -41    -52    -57    -17
    > 
    

    使用的数据:

    > gapminder_new
    # A tibble: 2 x 9
      country    `1960` `1961` `1962` `1963` `1964` `1965` `1966` `1967`
      <chr>       <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
    1 Bangladesh    372    384    394    381    411    405    402    382
    2 India         330    336    339    352    370    353    345    365
    > 
    

    【讨论】:

      【解决方案2】:

      当您过滤多个值时,您应该使用%in% 而不是==

      除此之外,当您拥有正确格式的数据时,数据操作变得非常容易。例如,对于您的情况,如果您将数据作为 2 列(即国家/地区的名称),会容易得多。

      library(dplyr)
      library(tidyr)
      
      tmp <- gapminder_new %>%
               pivot_longer(cols = -country) %>%
               pivot_wider(names_from = country, values_from = value)
      tmp
      
      # A tibble: 8 x 3
      #  name  Bangladesh India
      #  <chr>      <int> <int>
      #1 1960         372   330
      #2 1961         384   336
      #3 1962         394   339
      #4 1963         381   352
      #5 1964         411   370
      #6 1965         405   353
      #7 1966         402   345
      #8 1967         382   365
      

      现在获得两个国家之间的差异很简单:

      tmp %>% mutate(diff = India - Bangladesh)
      
      #  name  Bangladesh India  diff
      #  <chr>      <int> <int> <int>
      #1 1960         372   330   -42
      #2 1961         384   336   -48
      #3 1962         394   339   -55
      #4 1963         381   352   -29
      #5 1964         411   370   -41
      #6 1965         405   353   -52
      #7 1966         402   345   -57
      #8 1967         382   365   -17
      

      【讨论】:

      • 谢谢@Ronak,是的,我同意处理较长格式的数据更容易,而且我一直这样做到现在。但是当数据集真的很大时,我想走出舒适区并多次执行一些行明智的操作,然后我觉得仅仅为了一些减法或其他计算而对数据进行两次重塑并不是一个好主意。
      【解决方案3】:

      正如您要求的一种无需管道的方法,这里是一个:

      gapminder_new %>% 
        filter(country == c("India","Bangladesh")) # this is your code, rest without piping
      
      gapminder_new[1,]<-gapminder_new[1,]*-1
      
      gapminder_new<-apply(gapminder_new, 2, sum)
      

      【讨论】:

      • 我不确定它是否有效,因为这给了我错误:{r} test_set &lt;- gapminder_new %&gt;% filter(country %in% c("India","Bangladesh")) test_set[1,]&lt;-test_set[1,]*-1 test_set&lt;-apply(test_set, 2, sum) 但我从中明白了如何去做。
      【解决方案4】:

      这是我之前尝试过的解决方案,但可能因为 tibble 而失败。

      只需要在data frmae中将country设置为rownames,然后你可以根据base R中的国家名称进行减法。就是这样。对于刚开始并且不知道任何花哨功能的人来说,这是一种非常基本的方法。

      df

      gapminder_new         # latest gapminder data taken from gapminder website
      
      ########## output #########
      country 1960 1961 ...... 2019
      <chr> <dbl> <dbl> ...... <dbl>
      
      1   Afghanistan NA  NA  
      2   Albania NA  NA  
      3   Algeria 2480    2090    
      

      将其转换为data frame 并将country 设置为row names / row index

      test_set <- as.data.frame(gapminder_new)
      rownames(test_set) <- test_set$country
      
      head(test_set)
      ######## output ########
                  country 1960 1961 1962
                  <chr> <dbl>  <dbl> <dbl>
      
      Afghanistan Afghanistan NA  NA  NA  
      Albania     Albania NA  NA  NA  
      Algeria     Algeria 2480    2090    1640    
      

      根据所需的国家/地区名称减去

      test_set["India",2:ncol(test_set)] - test_set["Bangladesh",2:ncol(test_set)]
      
      ######### output ########
      1960 1961 1962 1963 1964 1965 1966 1967 1968
      India   -42 -48 -55 -29 -41 -52 -57 -17 -37
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-29
        • 1970-01-01
        • 1970-01-01
        • 2021-11-04
        相关资源
        最近更新 更多