Заполните ячейку dataframe вектором - PullRequest
0 голосов
/ 01 ноября 2019

Можно ли заполнить ячейку блока данных списком?

Это мой код:

input_vector <- sample(1:1000, 200)
input_vector

new_data_frame <- data.frame("Values" = numeric() , "Divisors" = numeric())
new_data_frame

for (i in input_vector) {
  if (i %% 3 == 0 & i %% 7 == 0) {
   new_data_frame[nrow(new_data_frame)+1, 1] <- i
   new_data_frame[nrow(new_data_frame), 2] <- c(3, 7)
  } 
  }

new_data_frame

Однако, похоже, я не могу заполнить второй столбец с помощью c(3,7). Запуск кода без этой следующей строки работает:

new_data_frame[nrow(new_data_frame), 2] <- c(3, 7)

Также, когда я добавляю числа 3 и 7 в виде строки, это работает. Почему я могу добавить строки в одну ячейку в кадре данных, но не в векторы или списки.

Ответы [ 2 ]

4 голосов
/ 01 ноября 2019

То, что вы пытаетесь использовать, называется list-column . Как правило, столбцы в кадрах - это векторы, а не списки, которые имеют (среди прочего) пару простых свойств: [ всегда возвращает элементарную вещь, и большинство операций, работающих с кадрами, работают со всеми столбцами. Как только столбец будет list вместо vector, некоторые вещи могут работать по-другому.

Для демонстрации:

mt <- head(mtcars)
### "set up" the third column as a list
mt[[3]] <- as.list(mt[[3]])

### while it "looks normal",
mt
#                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
# Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
# Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
# Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
# Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
# Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
# Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1

### ... its output is obviously different
mt[,2]
# [1] 6 6 4 6 8 6
mt[,3]
# [[1]]
# [1] 160
# [[2]]
# [1] 160
# [[3]]
# [1] 108
# [[4]]
# [1] 258
# [[5]]
# [1] 360
# [[6]]
# [1] 225

Отсюда вы можете использовать двойнуюОбозначение в скобках:

mt[[2,3]] <- c(3, 7)
mt
#                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
# Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
# Mazda RX4 Wag     21.0   6 3, 7 110 3.90 2.875 17.02  0  1    4    4
# Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
# Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
# Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
# Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1
mt[,3]
# [[1]]
# [1] 160
# [[2]]
# [1] 3 7
# [[3]]
# [1] 108
# [[4]]
# [1] 258
# [[5]]
# [1] 360
# [[6]]
# [1] 225

Некоторые вещи, которые «естественны» для неперечисленных кадров, начнут демонстрировать различия:

sapply(mt, class)
#       mpg       cyl      disp        hp      drat        wt      qsec        vs        am      gear      carb 
# "numeric" "numeric"    "list" "numeric" "numeric" "numeric" "numeric" "numeric" "numeric" "numeric" "numeric" 

colSums(head(mtcars))
#     mpg     cyl    disp      hp    drat      wt    qsec      vs      am    gear    carb 
#  123.00   36.00 1271.00  703.00   20.64   17.93  108.77    3.00    3.00   21.00   13.00 

colSums(mt)
# Error in colSums(mt) : 'x' must be numeric
sapply(mt, function(a) sum(unlist(a)))
#     mpg     cyl    disp      hp    drat      wt    qsec      vs      am    gear    carb 
#  123.00   36.00 1121.00  703.00   20.64   17.93  108.77    3.00    3.00   21.00   13.00 

и многие другие существуют.

1 голос
/ 01 ноября 2019

Это можно сделать, но не рекомендуется. Каждый столбец df должен иметь один и тот же класс, поэтому, если вы измените класс df с числового на список, вы можете поместить в него все, что захотите, хотя он может работать не так, как ожидалось! (как объяснено @ r2evans выше)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...