创建长度不等的 Dataframe

f45qwnt8  于 2023-05-26  发布在  其他
关注(0)|答案(6)|浏览(163)

虽然数据框列必须具有相同的行数,但是否有任何方法可以创建长度不等的数据框。我对将它们保存为列表的单独元素不感兴趣,因为我经常需要将这些信息作为csv文件通过电子邮件发送给人们,而这作为 Dataframe 是最简单的。

x = c(rep("one",2))
y = c(rep("two",10))
z = c(rep("three",5))
cbind(x,y,z)

在上面的代码中,cbind()函数只是回收较短的列,使它们每列都有10个元素。我怎样才能改变它,使长度为2,10和5。
我以前也这样做过,但效率很低。

df = data.frame(one=c(rep("one",2),rep("",8)), 
           two=c(rep("two",10)), three=c(rep("three",5), rep("",5)))
q3aa0525

q3aa05251#

对不起,这不是你问的,但我想可能有另一种方法来得到你想要的。
首先,如果向量的长度不同,数据就不是真正的表格,对吗?如何将其保存到不同的CSV文件?您也可以尝试使用允许存储多个对象的ascii格式(jsonXML)。
如果你觉得数据真的是表格式的,你可以在NA上填充:

> x = 1:5
> y = 1:12
> max.len = max(length(x), length(y))
> x = c(x, rep(NA, max.len - length(x)))
> y = c(y, rep(NA, max.len - length(y)))
> x
 [1]  1  2  3  4  5 NA NA NA NA NA NA NA
> y
 [1]  1  2  3  4  5  6  7  8  9 10 11 12

如果你一定要用不等列来做一个data.frame,你可能会破坏检查,后果自负:

> x = 1:5
> y = 1:12
> df = list(x=x, y=y)
> attributes(df) = list(names = names(df),
    row.names=1:max(length(x), length(y)), class='data.frame')
> df
      x  y
1     1  1
2     2  2
3     3  3
4     4  4
5     5  5
6  <NA>  6
7  <NA>  7
 [ reached getOption("max.print") -- omitted 5 rows ]]
Warning message:
In format.data.frame(x, digits = digits, na.encode = FALSE) :
  corrupt data frame: columns will be truncated or padded with NAs
csga3l58

csga3l582#

另一种填充方法:

na.pad <- function(x,len){
    x[1:len]
}

makePaddedDataFrame <- function(l,...){
    maxlen <- max(sapply(l,length))
    data.frame(lapply(l,na.pad,len=maxlen),...)
}

x = c(rep("one",2))
y = c(rep("two",10))
z = c(rep("three",5))

makePaddedDataFrame(list(x=x,y=y,z=z))

na.pad()函数利用了这样一个事实,即如果您尝试索引不存在的元素,R将自动使用NA填充向量。
makePaddedDataFrame()只找到最长的一个,并将其余的填充到匹配的长度。

unftdfkk

unftdfkk3#

为了放大@goodside的答案,你可以做一些类似的事情

L <- list(x,y,z)
cfun <- function(L) {
  pad.na <- function(x,len) {
   c(x,rep(NA,len-length(x)))
  }
  maxlen <- max(sapply(L,length))
  do.call(data.frame,lapply(L,pad.na,len=maxlen))
}
cfun(L)
pb3skfrl

pb3skfrl4#

您需要将NA填充到向量的末尾,以匹配最长向量的长度,因此您可以执行以下操作:

l <- tibble::lst(x, y, z)
data.frame(lapply(l, `length<-`, max(lengths(l))))

      x   y     z
1   one two three
2   one two three
3  <NA> two three
4  <NA> two three
5  <NA> two three
6  <NA> two  <NA>
7  <NA> two  <NA>
8  <NA> two  <NA>
9  <NA> two  <NA>
10 <NA> two  <NA>
2eafrhcq

2eafrhcq5#

我们可以创建一个包含不等长列的数据框,方法是用空字符“"填充列。以下代码可用于创建长度不等的 Dataframe
代码首先找到列表对象的最大列长度,l然后用“”填充列。这将导致列表的每一列都有相同数量的元素。然后将列表转换为 Dataframe 。

# The list column names
cols <- names(l)

# The maximum column length
max_len <- 0
for (col in cols){
    if (length(l[[col]]) > max_len)
        max_len <- length(l[[col]])
}

# Each column is padded
for (col in cols){
    l[[col]] <- c(l[[col]], rep("", max_len - length(l[[col]])))
}

# The list is converted to data frame
df <- as.data.frame(l)
niwlg2el

niwlg2el6#

类似问题:

coin <- c("Head", "Tail")
toss <- sample(coin, 50, replace=TRUE)

categorize <- function(x,len){
  count_heads <- 0
  count_tails <- 0
  tails <- as.character()
  heads <- as.character()
  for(i in 1:len){
    if(x[i] == "Head"){
      heads <- c(heads,x[i])
      count_heads <- count_heads + 1
    }else {
      tails <- c(tails,x[i])
      count_tails <- count_tails + 1
    }
  }
  if(count_heads > count_tails){
    head <- heads
    tail <- c(tails, rep(NA, (count_heads-count_tails)))
  } else {
    head <- c(heads, rep(NA,(count_tails-count_heads)))
    tail <- tails
  }
  data.frame(cbind("Heads"=head, "Tails"=tail))
}

categorize(toss,50)
输出:After the toss of the coin there will be 31 Head and 19 Tail. Then the rest of the tail will be filled with NA in order to make a data frame.

相关问题