R语言 如何使用窗口函数?

smtd7mpg  于 2023-02-26  发布在  其他
关注(0)|答案(2)|浏览(181)

bounty将在3天后过期。回答此问题可获得+100声望奖励。Khashir希望引起更多人对此问题的关注:我很想弄清楚这一点,因为理论上这应该是tidyverse包中的一个关键功能。

我正在努力让窗口函数在R中工作,以便按行数对组进行排序。
下面是我的示例代码:

data <- read_csv("https://dq-content.s3.amazonaws.com/498/book_reviews.csv")

data %>% 
    group_by(state) %>%
    mutate(num_books = n(),
           state_rank = dense_rank(num_books)) %>% 
    arrange(num_books)

预期的输出是原始数据将有一个新列,它告诉我每行(book、state、price和review)的排名,这取决于该行是否是书评最多的州(state_rank为1);第二多的书(等级2)等。

我可以手动获得如下输出:

data <- read_csv("https://dq-content.s3.amazonaws.com/498/book_reviews.csv")

manual_ranks <- data %>% 
  count(state) %>% 
  mutate(state_rank = rank(state))

desired_output <- data %>% 
  left_join(manual_ranks) %>% 
  arrange(state_rank)

sample_n(desired_output, 10)

换句话说,我需要此表的最后一列:

data %>% 
 count(state) %>% 
 mutate(state_rank = rank(state))

添加到原始表的每一行(而不必创建该表并随后使用left_join by state;这就是窗口函数的意义)。
无论如何,在原始代码中,您将看到所有state_rank都只显示为1,而我期望书评最多的州排名为1,评论第二多的州排名为2,以此类推。
我的目标是能够按state_rank > 4进行过滤,也就是说,我希望保留原始数据中书评最多的前4个州的所有行。

wfsdck30

wfsdck301#

我不太明白为什么你想排名的评论数量每个国家也没有分组的标题,也许给一些权重的价格,但你原来的描述:

library(tidyverse)
data <- read_csv("https://dq-content.s3.amazonaws.com/498/book_reviews.csv")

data <- data %>%
    group_by(state) %>% 
    mutate(reviews = sum(!is.na(review) == TRUE)) %>% 
    ungroup() %>% 
    mutate(state_rank = dense_rank(1/reviews), .keep = "unused")

这将允许您根据总评论数最多或最少的州来过滤数据。请注意,我删除了列reviews,但如果您想保留它,只需删除.keep = "unused"即可。
编辑:我最初忘了颠倒排名,这样评论最多的州排名最高(因为rank函数从低到高对数值进行排名)。使其成为1的分数是我能想到的最简单的方法。
此外,计算每组的评论数量利用了逻辑TRUE在R中等于1的事实。我假设你只想计算没有NA值的评论。我肯定想通过将评论转换为一个尺度来衡量评论-因此,一本只有poor评论的书在州排名上并不是一件好事。

pengsaosao

pengsaosao2#

首先,让我说,你的“手工方法”至少有两个问题,所以我不能100%确定我理解的问题是正确的。
问题1:使用以下公式计算秩:

manual_ranks <- data %>% 
  count(state) %>% 
  mutate(state_rank = rank(state))

表达式rank(state)state列进行运算,因此对州的names进行运算。这意味着州名在字母表中排在第一位的州排名最低。您可能希望通过图书计数来计算排名,因此需要mutate(state_rank = rank(n))
问题2:根据定义,统计等级不随值递减,因此具有最低计数的状态得到等级1。(当然,您可以很容易地转换结果;我只是想指出代码的输出与您的描述不符。
现在回到你的问题:
你说得对,窗口函数不会改变数据的形状(准确地说,它们不改变数据的行数),但它们的局限性在于它们只能对当前窗口的数据进行操作,您要计算不同州的账面数的排名,由于每个州都形成自己的组/窗口,这是一个涉及到不同集团/窗口的操作,你根本无法用窗口函数来解决。
如果你想避免使用帮助表和连接,你可以使用nest来收集一行中每个州的账簿,并在排名计算后使用unnest恢复所有内容。

data %>% 
  nest(books = c(-state)) %>% 
  mutate(state_rank = dense_rank(map_dbl(books, nrow))) %>% 
  unnest(books)

然而,就我个人而言,我更喜欢您所概述的“手动方法”,因为我发现它比nest()的替代方法要清楚得多。

相关问题