我正在尝试将Census API调用的输出(保存为.rds file here)转换为R数据框对象。为方便起见,我们调用对象'x'。
x的每个元素都是一个列表
# Both of below return 'list'
class(x[i])
class(x[[i]])
该列表的每个元素都是......
字符向量
# Returns 'list'
class(x[[i]][k])
# Returns 'character'
class(x[[i]][[k]])
列表
# Returns 'list'
class(x[[i]][k])
# Returns 'list'
class(x[[i]][[k]])
元素是列表还是字符向量的决定因素是值“NULL”是否出现在数据行中。如果该行的一个元素是“NULL”,则该元素是一个列表。如果该行的所有元素都不是“NULL”,那么该元素就是一个字符向量。
如果以上是列表,如果值为NULL,则列表中的每个元素都是“NULL”类;如果值不是“NULL”,则列表中的每个元素都是类字符
# Returns 'list'
class(x[[i]][[k]][g])
# Returns "NULL" if "NULL" else "character"
class(x[[i]][[k]][[g]])
有人可以提出将其转换为数据框的方法吗?我很难搞清楚如何将块组元素转换为我可以应用(或循环)的对象。
响应可重现示例的请求,请参阅以下代码。它演示了我的数据的小版本(我的数据包含许多县,黑组和变量)。请注意,每个块组向量或列表的长度等于变量的数量,因为向量的元素是该相应变量的块组的值。我的目标是生成一个列名为var1,var2,var3,var4的数据框,而每一行代表一个块组的值。
set.seed(5)
# County 1
bezz <- c("var1","var2","var3","var4") # variable names
bizz <- as.character(round(rnorm(4),2)) # block group 1.1
buzz <- list("NULL","NULL","2","94389") # block group 1.2
bozz <- as.character(round(rnorm(4),2)) # block group 1.3
bazz <- list("NULL","NULL","888888888","NULL") # block group 1.4
foo <- list(bezz, bizz,buzz,bozz,bazz) # county 1 object
# County 2
fezz <- c("var1","var2","var3","var4") # variable names
fizz <- list("NULL","2","NULL","94389") # block group 2.1
fuzz <- as.character(round(rnorm(4),2)) # block group 2.2
fozz <- as.character(round(rnorm(4),2)) # block group 2.3
bar <- list(fezz, fizz,fuzz,fozz) # county 2 object
# County 3
lezz <- c("var1","var2","var3","var4") # variable names
luzz <- as.character(round(rnorm(4),2)) # block group 3.1
baz <- list(lezz, luzz) # county 3 object
# API output
mydata <- list(foo,bar,baz) # all counties in a list
答案 0 :(得分:1)
此解决方案要求将所有NULL
转换为NA
。由于所有数据都显示为数字,因此使用了as.numeric()
,如果不是您想要的话,只需删除。
这应该需要一段时间,也许有更有效的方法来解决这个问题。这两个循环可以合二为一,但为了清楚起见,NULL
到NA
循环已经分开了。
have <- readRDS("~/R/SO/acs0509_block_group_call.Rds")
# replace NULL's with NA's
for(i in seq_along(have)) {
for(j in seq_along(have[[i]])) {
for(k in seq_along(have[[i]][[j]])) {
have[[i]][[j]][[k]] <- ifelse(is.null(have[[i]][[j]][[k]]),NA,have[[i]][[j]][[k]])
}
}
}
# initiate "want" data.frame with an arbitrary row
want <- as.data.frame(t(as.numeric(have[[1]][[2]])))
colnames(want) <- have[[1]][[1]]
ins.row <- 1
for(i in 1:length(have)) {
for(j in 2:(length(have[[i]]))) {
if(is.list(have[[i]][[j]]))
want[ins.row,] <- as.numeric(unlist(have[[i]][[j]]))
else
want[ins.row,] <- as.numeric(have[[i]][[j]])
ins.row <- ins.row + 1
}
}