0

为什么这不适用于示例?每行都有相同的值和警告

data <- data.frame(id = 1:10)
slowCall <- function(id) data.frame(b = rep(id, 3), c = runif(3))
data[,c("d", "e")] <- sapply(data$id, function(id) {
 tmp <- slowCall(id)
 list(sum(tmp$b), min(tmp$c))
})

Warning message:
In `[<-.data.frame`(`*tmp*`, , c("d", "e"), value = list(3L, 0.104784948984161,  :
 provided 20 variables to replace 2 variables
print(data)
   id d         e
1   1 3 0.1047849
2   2 3 0.1047849
3   3 3 0.1047849
4   4 3 0.1047849
5   5 3 0.1047849
6   6 3 0.1047849
7   7 3 0.1047849
8   8 3 0.1047849
9   9 3 0.1047849
10 10 3 0.1047849
4

3 回答 3

0

这里的问题是您返回的矩阵sapply包含单元素列表而不是数值。将您的更改list为 ac并转置输出,然后它将起作用。

data[, c("d", "e")] <- t(sapply(data$id, function(id) {
  tmp <- slowCall(id)
  c(sum(tmp$b), min(tmp$c))
}))
于 2013-10-23T05:52:07.747 回答
0

你可以试试这样的。首先,对assign函数进行矢量化(根据@Joran在此处的回答),然后稍微修改您的代码。

# vectorize
assignVec <- Vectorize("assign",c("x","value"))

library(plyr)
set.seed(1) # this is just here for reproducibility

data <- data.frame(id = 1:10)
slowCall <- function(id) data.frame(b = rep(id, 3), c = runif(3))

# I store this as `tmp` just to make the code below look cleaner
tmp <- mlply(sapply(data$id, function(id) {
    tmp <- slowCall(id)
    list(sum(tmp$b), min(tmp$c))
}), c)

# here's the key part:
data <- within(data, assignVec(c('d','e'), tmp, envir=environment()))

输出:

> data
   id          e  d
1   1 0.26550866  3
2   2 0.20168193  6
3   3 0.62911404  9
4   4 0.06178627 12
5   5 0.38410372 15
6   6 0.49769924 18
7   7 0.38003518 21
8   8 0.12555510 24
9   9 0.01339033 27
10 10 0.34034900 30

注意:我调用plyr::mlply以将您的sapply输出放入列表中。

不过,更简单的答案是将操作的右侧更改为:

data[,c("d", "e")] <- as.data.frame(t(sapply(data$id, function(id) {
 tmp <- slowCall(id)
 list(sum(tmp$b), min(tmp$c))
})))

这会给你同样的结果。

于 2013-10-22T22:30:52.643 回答
0

这是添加两列不同数据类型(例如字符和数字)的通用方法。它使用列表和转置列表(通过这个答案)。

在这里,这个答案将保留两个输出的整数和数字类型。

rowwise <- lapply(data$id, function(id) {
  tmp <- slowCall(id)
  list(sum(tmp$b), min(tmp$c))
})
colwise <- lapply(seq_along(rowwise[[1]]), function(i) lapply(rowwise, "[[", i))

data[,c("d", "e")] <- colwise
于 2013-11-27T17:46:51.710 回答