我有一个数据框,其中x是文本字符串,y是数字id:
x = c("a", "b", "c", "b", "a")
y = c(1,2,3,4,5)
df <- data.frame(x, y)
我希望找到列x中的所有匹配项,并为它们分配与y中第一个相同的数值。我用以下方法解决了这个问题:
library(foreach)
library(iterators)
for(i in 1:NROW(df)) {
for(j in i:NROW(df)) {
if(df$x[j] == df$x[i]){
df$y[j] <- df$y[i]
}
j = j + 1
}
i = i + 1
}
问题是,我有一个相当大的数据集,这使得这个过程需要花费很多时间!希望这里的任何人都知道更少的时间消息!
答案 0 :(得分:2)
如果您的数据集确实很大,那么data.table可能是最快的解决方案(参见基准here)。
library(data.table)
setDT(df)
df[, y := first(y), by = x]
答案 1 :(得分:1)
R喜欢矢量化代码,因此如果在循环中完成,算术运算和赋值等操作会很慢。例如,考虑以两种不同的方式将向量1,2,... 1,000,000分配给变量x
x <- 1:1e6
和
x <- numeric(x, 1e6) # initialise a numeric vector of length 1 million
for (i in 1:1e6) x[i] <- i
如果你试试这个,你会发现第二种方法需要更长的时间。
遇到问题,您希望按df$x
中的值对数据进行分组,并将y
的值替换为第一个元素
df.by <- by(df$x, function(d) transform(d, y = y[1]), data = df)
将df
的每个子集的第二列(基于df$x
的子集)设置为等于其第一个元素。结果是
#df$x: a
# x y
#1 a 1
#5 a 1
#------------------------------------------------------------
#df$x: b
# x y
#2 b 2
#4 b 2
#------------------------------------------------------------
#df$x: c
# x y
#3 c 3
要将这些组合回数据框,请使用df.new <- do.call(rbind, df.by)
。此操作的一个(可能不需要的)副作用是它将改变行的顺序。
如果您是R的新手,请查看dplyr
包,它具有流畅的学习曲线,并且易于编写和阅读语法。您想要做的只需几行即可完成。
library(dplyr)
df %>% group_by(x) %>% mutate(y = y[1])
会做到的!