我有一个这样的数据框:
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
我希望访问我的每个级别的第一个元素(在这个例子中包含a, c, e
的矢量)。
可以使用
到达一个级别的第一个元素df$s[df$n == 2][1]
但它并不适用于所有级别:
df$s[df$n == levels(n)]
[1] a f
你会怎么做?
为了更进一步,我想修改我的数据框,看看哪个是每次出现的每个级别的第一个元素。在我的示例中,新列应为:
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
答案 0 :(得分:16)
修改即可。我的答案的第一部分解决了原始的问题,即之前“并且更进一步”(在编辑中由OP添加)。
使用duplicated
的另一种可能性。从?duplicated
:“duplicated()
确定向量或数据框的哪些元素与具有较小下标的元素重复。”
这里我们使用!
,逻辑否定(NOT)来选择不'n'的重复元素,即每个'n'级别的第一个元素。
df[!duplicated(df$n), ]
# n s
# 1 2 a
# 3 3 c
# 5 4 e
更新直到现在才看到您的“并进一步”编辑。我的第一个建议肯定是使用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
或全面使用dplyr
便捷功能并使用first
代替[1]
:
df %.%
group_by(n) %.%
mutate(
first = first(s))
原始问题的dplyr
解决方案是使用summarise
:
df %.%
group_by(n) %.%
summarise(
first = first(s))
# n first
# 1 2 a
# 2 3 c
# 3 4 e
答案 1 :(得分:11)
以下是使用match
的方法:
df$s[match(levels(n), df$n)]
编辑:也许这看起来有点令人困惑......
要获取列出第一个元素的列,您可以使用match
两次(但交换x
和table
个参数):
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
让我们详细看一下:
## 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
答案 2 :(得分: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
答案 3 :(得分:4)
在这种情况下,我更喜欢plyr包,它可以进一步自由地操纵数据。
library(plyr)
ddply(df,.(n),function(subdf){return(subdf[1,])})
n s
1 2 a
2 3 c
3 4 e
答案 4 :(得分:4)
您也可以使用data.table
library(data.table)
dt = as.data.table(df)
dt[, list(firstelement = s[1]), by=n]
哪能得到你:
n firstelement
1: 2 a
2: 3 c
3: 4 e
by=n
位按n
的每个值对所有内容进行分组,因此s[1]
获取每个组的第一个元素。
要将此作为额外的列,您可以这样做:
dt[, newcol := s[1], by=n]
dt
# n s newcol
#1: 2 a a
#2: 2 b a
#3: 3 c c
#4: 3 d c
#5: 4 e e
#6: 4 f e
所以这只是从每个组的第一行获取s
的值并将其分配给新列。
答案 5 :(得分:2)
df$s[sapply(levels(n), function(particular.level) { which(df$n == particular.level)[1]})]
我相信你的问题是你正在比较两个向量df $ n是一个向量而level(n)是一个向量。 vector == vector恰好适合你,因为df $ n是level(n)的倍数长度
答案 6 :(得分:0)
感到惊讶的是还没有在答案流中看到这个经典。
> do.call(rbind, lapply(split(df, df$n), function(x) x[1,]))
## n s
## 2 2 a
## 3 3 c
## 4 4 e