无法将数据框绑定到空数据框
Can't rbind a data frame to an empty data frame
我正在学习 R Studio,这是针对我正在进行的项目。我正在使用 Marvel API 通过使用 for 循环多次调用 API 来获取宇宙中所有角色的列表。他们 API 将您限制为 100 results/call,因此我正在迭代并为每个循环设置偏移量。
我的代码在过去几天运行正常,但是当我今天加载并尝试获取数据时,出现错误:“rbind(deparse.level, ...) 错误:无效的列表参数:所有变量的长度应相同
这是我的代码 运行:
MarvelUniverse = data.frame()
y = 1
offset = c(0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400)
for(x in offset){
partialUrl = "https://gateway.marvel.com:443/v1/public/characters?ts=1&apikey={apiKey}&hash={hash}&limit=100&offset="
url = paste(partialUrl, offset, sep="")
call = httr::GET(url[y])
query = httr::content(call, as="raw")
name = jsonlite::fromJSON(rawToChar(query))
df = flatten(as.data.frame(name))
MarvelUniverse = rbind(df, MarvelUniverse)
y = y + 1
}
因为我之前绑定的是一个空数据框,所以我不明白为什么我以前可以使用这个功能,但现在却失败了?我确实注意到 df
现在持有 1618 个元素,它在中断前持有 ~1498 个元素。 name
列表仍然包含一个包含 7 个元素的大列表,所以看起来是一样的。
编辑
我发现如果我从 df = flatten(as.data.frame(name))
中删除 flatten,调用将在循环的第一次迭代中执行,但现在我 运行 遇到了重复 row.names 的问题。试图将它们设置为 NULL,但不幸的是,到目前为止还没有成功。
几点建议:
不要 rbind()
循环中一次一个数据帧 - 这是一种典型的反模式。它被称为“增长一个对象”并且是2nd Circle of Hell in the R Inferno。这是非常低效的。相反,您应该将所有数据框放在一个列表中,然后 rbind
最后一次将它们全部放在一起。
您在同一个循环中使用了两个循环变量:x
和 y
。 x
是 for()
中指定的那个,而 y
您正在手动跟踪。这很容易出现错误 - 只需使用一个循环变量(几乎总是最好让循环变量超过 1, 2, 3, ..., n)
解决这些问题,我会试试这个代码:
MarvelUniverseList = list()
offset = c(0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400)
for(i in seq_along(offset)){
partialUrl = "https://gateway.marvel.com:443/v1/public/characters?ts=1&apikey={apiKey}&hash={hash}&limit=100&offset="
url = paste(partialUrl, offset[i], sep="")
call = httr::GET(url[i])
query = httr::content(call, as="raw")
name = jsonlite::fromJSON(rawToChar(query))
MarvelUniverseList[[i]] = flatten(as.data.frame(name))
}
## combine at end
MarvelUniverse = do.call(rbind, MarvelUniverseList)
## more efficient and flexible version from dplyr
MarvelUniverse = dplyr::bind_rows(MarvelUniverseList)
当然,如果没有 API 密钥,我无法对此进行测试或查看您的问题所在。 dplyr::bind_rows
比 rbind
更灵活一点,所以它可能会解决你的问题。但这种方法还有一个优点,如果合并数据框时出现问题,您可以将单独的数据框存储在列表中,您可以 inspect/debug/fix 它们以便合并。
我正在学习 R Studio,这是针对我正在进行的项目。我正在使用 Marvel API 通过使用 for 循环多次调用 API 来获取宇宙中所有角色的列表。他们 API 将您限制为 100 results/call,因此我正在迭代并为每个循环设置偏移量。
我的代码在过去几天运行正常,但是当我今天加载并尝试获取数据时,出现错误:“rbind(deparse.level, ...) 错误:无效的列表参数:所有变量的长度应相同
这是我的代码 运行:
MarvelUniverse = data.frame()
y = 1
offset = c(0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400)
for(x in offset){
partialUrl = "https://gateway.marvel.com:443/v1/public/characters?ts=1&apikey={apiKey}&hash={hash}&limit=100&offset="
url = paste(partialUrl, offset, sep="")
call = httr::GET(url[y])
query = httr::content(call, as="raw")
name = jsonlite::fromJSON(rawToChar(query))
df = flatten(as.data.frame(name))
MarvelUniverse = rbind(df, MarvelUniverse)
y = y + 1
}
因为我之前绑定的是一个空数据框,所以我不明白为什么我以前可以使用这个功能,但现在却失败了?我确实注意到 df
现在持有 1618 个元素,它在中断前持有 ~1498 个元素。 name
列表仍然包含一个包含 7 个元素的大列表,所以看起来是一样的。
编辑
我发现如果我从 df = flatten(as.data.frame(name))
中删除 flatten,调用将在循环的第一次迭代中执行,但现在我 运行 遇到了重复 row.names 的问题。试图将它们设置为 NULL,但不幸的是,到目前为止还没有成功。
几点建议:
不要
rbind()
循环中一次一个数据帧 - 这是一种典型的反模式。它被称为“增长一个对象”并且是2nd Circle of Hell in the R Inferno。这是非常低效的。相反,您应该将所有数据框放在一个列表中,然后rbind
最后一次将它们全部放在一起。您在同一个循环中使用了两个循环变量:
x
和y
。x
是for()
中指定的那个,而y
您正在手动跟踪。这很容易出现错误 - 只需使用一个循环变量(几乎总是最好让循环变量超过 1, 2, 3, ..., n)
解决这些问题,我会试试这个代码:
MarvelUniverseList = list()
offset = c(0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400)
for(i in seq_along(offset)){
partialUrl = "https://gateway.marvel.com:443/v1/public/characters?ts=1&apikey={apiKey}&hash={hash}&limit=100&offset="
url = paste(partialUrl, offset[i], sep="")
call = httr::GET(url[i])
query = httr::content(call, as="raw")
name = jsonlite::fromJSON(rawToChar(query))
MarvelUniverseList[[i]] = flatten(as.data.frame(name))
}
## combine at end
MarvelUniverse = do.call(rbind, MarvelUniverseList)
## more efficient and flexible version from dplyr
MarvelUniverse = dplyr::bind_rows(MarvelUniverseList)
当然,如果没有 API 密钥,我无法对此进行测试或查看您的问题所在。 dplyr::bind_rows
比 rbind
更灵活一点,所以它可能会解决你的问题。但这种方法还有一个优点,如果合并数据框时出现问题,您可以将单独的数据框存储在列表中,您可以 inspect/debug/fix 它们以便合并。