2

我是 R 新手,想知道执行以下操作的最佳方法是什么 -

我的实际问题是一个多元回归模型,但它是一个相当大的数据集(> 5000 行和 12 列),因此我设计了一个类似的更短的问题。可以复制以下问题的解决方案来解决我的实际问题。以下任何帮助(包括速度问题)将不胜感激 - 我有以下两个数据框 - d1 和 d2

d1 -
   sno letter age
   1      a  29
   2      b  30
   3      a  33
   4      b  22
   5      c  25
d2-
  letter marks
     a    40
     b    90
     c    60

现在,我想使用marks_code从d2计算a、b、c是通过还是失败,然后在d1中包含相应的成绩。所以我的最终输出应该是这样的——

d1 -
   sno letter age grade
   1      a  29     0
   2      b  30     1
   3      a  33     0
   4      b  22     1
   5      c  25     1

下面是我写的代码——(我没有得到我想要的结果!)

d1 <- data.frame(cbind(1:5,c("a","b","a","b","c"),c(29,30,33,22,25)),stringsAsFactors=FALSE )
colnames(d1) <- c("sno","letter","age")

d2 <- data.frame(cbind(c("a","b","c"),c(40,90,60)),stringsAsFactors=FALSE)
colnames(d2) <- c("letter","marks")

d2$grade <- rep(NA,3) #initialising the vector
d2$grade <- sapply(d2$marks,marks_code)
d1$grade <- rep(NA,5)
d1_coding(d1$letter)

d1_coding <- function(y1)
{
  letter_names <- unique(y1)
  m <- length(letter_names)
  for(i in 1:m)
  {
    sub <- subset(d1,d1$letter==letter_name[i])
    num_obs <- length(sub$sno)
    sub$grade <- rep(d2$grade[i],num_obs)
    merge(d1,sub,by="sno")
  }
 return(d1) 
}

marks_code <- function(y)
{
  a <-NA
  if(y<=40)
    a <- 0#fail
  else
    a<- 1#pass
  return(a)
}

提前非常感谢!:)

4

3 回答 3

1

使用data.table

require(data.table)
d1 <- as.data.table(d1)
d2 <- as.data.table(d2)
setkey(d1, "letter")
setkey(d2, "letter")
out <- d2[d1][, grade := (marks > 40) * 1]
setcolorder(out, c("letter", "sno", "age", "marks", "grade"))

 #    letter sno age marks grade
 # 1:      a   1  29    40     0
 # 2:      a   3  33    40     0
 # 3:      b   2  30    90     1
 # 4:      b   4  22    90     1
 # 5:      c   5  25    60     1

如果您想要相同的订单,您可以将 key 设置回“sno”,如下所示:

setkey(out, "sno")
于 2013-05-24T07:26:03.830 回答
0

这是一种不同的方法:

d1$grade <- 
as.numeric(sapply(d1$letter, FUN=function(z) d2[d2$letter==z,"marks"]>40))

还有一个,没有sapply

d1$grade <- 
as.numeric(d2$marks[pmatch(d1$letter, d2$letter, duplicates.ok=TRUE)] > 40)
于 2013-05-24T07:25:00.763 回答
0

你应该使用它ifelse,因为if它不像是矢量化的。

d1 <- read.table(text="  sno letter age
1      a  29
2      b  30
3      a  33
4      b  22
5      c  25",header=TRUE)

d2 <- read.table(text="  letter marks
a    40
b    90
c    60",header=TRUE)

res <- merge(d1,d2)
res$grade <- ifelse(res$marks <= 40, 0, 1)

res <- res[order(res$sno),]

#   letter sno age marks grade
# 1      a   1  29    40     0
# 3      b   2  30    90     1
# 2      a   3  33    40     0
# 4      b   4  22    90     1
# 5      c   5  25    60     1
于 2013-05-24T07:20:18.337 回答