在R中,如何访问因子的每个级别的第一个元素?

had*_*enj 20 r r-factor

我有一个这样的数据框:

n = c(2, 2, 3, 3, 4, 4) 
n <- as.factor(n)
s = c("a", "b", "c", "d", "e", "f") 
df = data.frame(n, s)  

df
  n s
1 2 a
2 2 b
3 3 c
4 3 d
5 4 e
6 4 f
Run Code Online (Sandbox Code Playgroud)

我想访问我的因子的每个级别的第一个元素(在这个例子中有一个包含的向量a, c, e).

有可能达到一个级别的第一个元素

df$s[df$n == 2][1]
Run Code Online (Sandbox Code Playgroud)

但它并不适用于所有级别:

df$s[df$n == levels(n)]
[1] a f
Run Code Online (Sandbox Code Playgroud)

你会怎么做?

更进一步,我想修改我的数据框,看看哪个是每次出现的每个级别的第一个元素.在我的示例中,新列应该是:

  n s rep firstelement
1 2 a   a            a
2 2 b   c            a
3 3 c   e            c
4 3 d   a            c
5 4 e   c            e
6 4 f   e            e
Run Code Online (Sandbox Code Playgroud)

Hen*_*rik 16

编辑.我的答案的第一部分解决了原始问题,即 "并且进一步"之前(在编辑中由OP添加).

另一种可能性,使用duplicated.From ?duplicated:" duplicated()确定向量或数据框的哪些元素与具有较小下标的元素重复."

在这里,我们使用!逻辑否定(NOT)来选择不是 'n'的重复元素,即每个级别'n'的第一个元素.

df[!duplicated(df$n), ]
#   n s
# 1 2 a
# 3 3 c
# 5 4 e
Run Code Online (Sandbox Code Playgroud)

更新到目前为止没有看到你的"进一步"编辑.我的第一个建议肯定是使用ave,正如@thelatemail和@sparrow已经提出的那样.但只是在R工具箱中挖掘并向您展示另一种选择,这是一种dplyr方式:

对数据进行分组n,使用mutate函数创建一个新的变量'first',其值为's'(s[1])的第一个元素,

library(dplyr)

df %.%
  group_by(n) %.%
  mutate(
    first = s[1])
#   n s first
# 1 2 a     a
# 2 2 b     a
# 3 3 c     c
# 4 3 d     c
# 5 4 e     e
# 6 4 f     e
Run Code Online (Sandbox Code Playgroud)

或者全部使用dplyr便利功能并使用first而不是[1]:

df %.%
  group_by(n) %.%
  mutate(
    first = first(s))
Run Code Online (Sandbox Code Playgroud)

一个dplyr为你原来的问题的解决办法是使用summarise:

df %.%
  group_by(n) %.%
  summarise(
    first = first(s))

#   n first
# 1 2     a
# 2 3     c
# 3 4     e
Run Code Online (Sandbox Code Playgroud)


sgi*_*ibb 11

这是一种使用方法match:

 df$s[match(levels(n), df$n)]
Run Code Online (Sandbox Code Playgroud)

编辑:也许这看起来有点令人困惑......

要获得一个列出第一个元素的列,您可以使用match两次(但使用xtable参数交换):

 df$firstelement <- df$s[match(levels(n), df$n)[match(df$n, levels(n))]]
 df$firstelement
 # [1] a a c c e e
 # Levels: a b c d e f
Run Code Online (Sandbox Code Playgroud)

让我们详细看一下:

 ## this returns the first matching elements
 match(levels(n), df$n)
 # [1] 1 3 5

 ## when we swap the x and table argument in match we get the level index
 ## for each df$n (the duplicated indices are important)
 match(df$n, levels(n))
 # [1] 1 1 2 2 3 3

 ## results in
 c(1, 3, 5)[c(1, 1, 2, 2, 3, 3)]
 # [1] 1 1 3 3 5 5
 df$s[c(1, 1, 3, 3, 5, 5)]
 # [1] a a c c e e
 # Levels: a b c d e f
Run Code Online (Sandbox Code Playgroud)


spa*_*row 6

该函数ave在这些情况下很有用:

df$firstelement = ave(df$s, df$n, FUN = function(x) x[1])
df
  n s firstelement
1 2 a            a
2 2 b            a
3 3 c            c
4 3 d            c
5 4 e            e
6 4 f            e
Run Code Online (Sandbox Code Playgroud)