2014-05-12 34 views
0

我是R的新用户,我不知道如何改进以下脚本。我听说过应用功能,但我没有设法使用它们。 这里是我的问题:通过使用应用函数避免for循环

我有两个数据帧,第一个叫data,第二个叫ecodata有超过100万行和eco 90.000。他们都有一个共同的列名为id。对于一个id,他们在data几行对应的植物物种的存在。

我想通过在数据帧中提供一个值给ideco如果一个特定种类的存在或data在同一id缺少symplify此。这些信息将出现在speco列中。

我在for循环脚本,它需要时间来运行:

for (k in (1:nrow(data))) { 
if (data[k, "sp"]==1) #sp corresponds to one specific specie 
{ 
eco[which(eco$id==data[k, "id"]), "sp"] = 1 # before this, the "sp" columnis empty in eco 
} 
} 

我怎么能提高呢?

非常感谢您的帮助。

回答

1

这是你在找什么?评论后

编辑由@Simon:

eco$sp <- 0       #create new column `sp` initialized with 0 
eco[eco$id %in% data$id[data$sp == 1],"sp"] <- 1 # replace 0 with 1 if for all id where data$sp == 1 
+0

@ SimonO'Hanlon感谢您的评论。我更新了我的答案 –

+0

这就是我一直在寻找的。非常感谢,它没有时间跑! – user3443183

2

随着1,000,000记录时,我会考虑使用data.table。您可以使用data.table的复合连接操作之一来执行此操作,这只是data[sp==1,][eco],如果您不介意NA在物种1不存在时返回。你有完美的设置。两个表与一个共同的关键。你可以很容易地这样做:

# Some sample data 
set.seed(123) 
data <- data.frame(id = rep(letters[1:3] , each = 3) , sp = sample(1:5 , 9 , TRUE)) 
eco <- data.frame(id = letters[1:3] , otherdat = rnorm(3)) 
data 
    id sp 
#1: a 2 
#2: a 4 
#3: a 3 
#4: b 5 
#5: b 5 
#6: b 1 ===> species 1 is present at this id only 
#7: c 3 
#8: c 5 
#9: c 3 

eco 
# id otherdat 
#1: a -0.1089660 
#2: b -0.1172420 
#3: c 0.1830826 


# All you need to do is turn your data.frames to data.tables, with a key, like so... 
require(data.table) 
data <- data.table(data , key = "id") 
eco <- data.table(eco , key = "id") 

# Join relevant records from data to eco by the common key 
# This way keep 0 when species 1 is present and 0 otherwise 
eco[ data[ , list(sp = as.integer(any(sp == 1))) , by = id ] ] 
# id otherdat sp 
#1: a -0.1089660 0 
#2: b -0.1172420 1 
#3: c 0.1830826 0 

# A more succinct way of doing this (and faster) 
# is a compound join (but you get NA instead of 0) 
data[sp==1,][eco] 
# id sp otherdat 
#1: a NA -0.1089660 
#2: b TRUE -0.1172420 
#3: c NA 0.1830826 
+0

非常感谢,它工作得很好。 – user3443183