【问题标题】:R: Sorting Columns in Dataframe based on Associated values?R:根据关联值对数据框中的列进行排序?
【发布时间】:2018-10-17 10:19:06
【问题描述】:

假设我有一个这样的数据框:

df <- data.frame(First_Name=c("John","Alex","James","John","Alex","John","James"),
             Last_Name = c("Smith","Smith","Jones","Jones","Johnson","Ryan","Murphy"),
             Frequency = c(4,7,8,9,3,10,4))

  First_Name Last_Name Frequency
1       John     Smith         4
2       Alex     Smith         7
3      James     Jones         5
4       John     Jones         9
5       Alex   Johnson         3
6       John      Ryan        10
7      James    Murphy         4

我想将第一列(名字)仅折叠为唯一值,并根据其累积频率对名称进行排序。对于此示例,如果我们这样做并按降序排序,则顺序将是:John、James、Alex,因为它们各自的累积频率分别为 23、10 和 12。

来自 python 背景,我正在考虑将值存储在一个元组中,但我不确定 R 中是否有等价物(目前,我只熟悉向量)。

此外,如果我尝试仅从“First_Name”列中提取唯一值并将其存储在向量中:

unique(c(df$First_Name))

R 输出这个:

[1] 3 1 2

这似乎表明他们将名称转换为整数。

所以我的问题是:

1) 我将如何只获取唯一的名字并根据它们的累积值对它们进行排序?

2) 如果我尝试将名称存储在向量中,为什么 R 会将名称转换为整数?

【问题讨论】:

  • 你得到数字是因为它们在内部是factors;尝试data.frame(...,stringsAsFactors=FALSE) 并重复。 (这是data.frameread.csv 和其他base-R read.* 函数使用的常用参数;许多人认为它应该默认为TRUE。)顺便说一句:试试sort(table(df$First_Name),decreasing=TRUE)

标签: r sorting dataframe vector


【解决方案1】:

R 默认将字符更改为因子,这可能会很烦人。您可以通过以下命令检查:

str(df)

哪个显示

'data.frame':   7 obs. of  3 variables:
 $ First_Name: Factor w/ 3 levels "Alex","James",..: 3 1 2 3 1 3 2
 $ Last_Name : Factor w/ 5 levels "Johnson","Jones",..: 5 5 2 2 1 4 3
 $ Frequency : num  4 7 8 9 3 10 4

如果您添加 stringsAsFactors 标志,您将避免这种情况:

df <- data.frame(First_Name=c("John","Alex","James","John","Alex","John","James"),
             Last_Name = c("Smith","Smith","Jones","Jones","Johnson","Ryan","Murphy"),
             Frequency = c(4,7,8,9,3,10,4), stringsAsFactors = FALSE)
str(df)
'data.frame':   7 obs. of  3 variables:
 $ First_Name: chr  "John" "Alex" "James" "John" ...
 $ Last_Name : chr  "Smith" "Smith" "Jones" "Jones" ...
 $ Frequency : num  4 7 8 9 3 10 4

但无论哪种方式,您都可以按唯一分组并使用聚合获取该子集的任何函数:

aggregate(Frequency ~ First_Name, data=df, FUN="sum")
  First_Name Frequency
1       Alex        10
2      James        12
3       John        23

表格可以使用order函数重新排序

out <- out[rev(order(out$Frequency)),]
  First_Name Frequency
3       John        23
2      James        12
1       Alex        10

如果您想按累积汇总重新排序第一个表,并保持原样,则需要合并。

out$rank <- 1:nrow(out)
new <- merge(df, out, by.x='First_Name', by.y='First_Name')
final <- new[order(new$rank),]

  First_Name Last_Name Frequency.x Frequency.y rank
1       Alex     Smith           7          10    1
2       Alex   Johnson           3          10    1
3      James     Jones           8          12    2
4      James    Murphy           4          12    2
5       John     Smith           4          23    3
6       John     Jones           9          23    3
7       John      Ryan          10          23    3

然后删除不需要的列。

【讨论】:

    【解决方案2】:

    您可以尝试tidyverse 解决方案

    library(tidyverse)
    df %>% 
      group_by(First_Name) %>% 
      summarise(Sum=sum(Frequency))
    # A tibble: 3 x 2
      First_Name   Sum
      <fct>      <dbl>
    1 Alex          10
    2 James         12
    3 John          23
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-04
      • 2019-08-10
      • 2020-05-15
      • 2022-12-18
      • 2021-10-29
      • 2019-01-18
      • 2012-09-03
      • 1970-01-01
      相关资源
      最近更新 更多