Функция base reshape
работает отлично:
df <- data.frame(
year = c(rep(2000, 12), rep(2001, 12)),
month = rep(1:12, 2),
values = rnorm(24)
)
df_wide <- reshape(df, idvar="year", timevar="month", v.names="values", direction="wide", sep="_")
df_wide
Здесь idvar
- столбец классов, который разделяет строки, timevar
- столбец классов, который должен быть широко представлен, v.names
- это столбец, содержащий числовые значения, direction
указывает широкий или длинный формат, а необязательный аргумент sep
- это разделитель, используемый между именами классов timevar
и v.names
на выходе data.frame
. Если нет idvar
, создайте его перед использованием функции reshape()
:
df$id <- c(rep("year1", 12), rep("year2", 12))
df_wide <- reshape(df, idvar="id", timevar="month", v.names="values", direction="wide", sep="_")
df_wide
Просто помните, что требуется idvar
! Часть timevar
и v.names
проста. Выход этой функции более предсказуем, чем некоторые другие, поскольку все явно определено.
Если вы объявляете свою переменную в классе как общедоступные переменные, вы можете получить к ней доступ следующим образом:
public partial class _Default : System.Web.UI.Page
{
public string message1 = null;
public string message2 = null;
public string message3 = null;
public void setVars()
{
for (int i = 1; i <=3; i++)
{
this.GetType().GetField("message" + i.ToString()).SetValue(this, "blabla" + i.ToString());
}
}
}
Вы не хотите, чтобы 3 переменные с тем же именем, вам нужен массив этих переменных.
string[] messages = new string[3]; // 3 item array
Затем вы можете сохранить свои элементы в элементах массива
messages[0] = "Apple"; // array index starts at 0!
messages[1] = "Banana";
messages[2] = "Cherry";
Другой способ создания этого массива - инициализатор встроенного массива, сохраняет некоторый код
string[] messages = { "Apple", "Banana", "Cherry" };
(Примечание: существуют более сильные синтаксисы для инициализации массива. Исследование различных других методов остается в виде упражнения.)
И получить к ним доступ через цикл (foreach)
foreach (string fruit in messages)
{
Console.WriteLine("I'm eating a " + fruit);
}
Или для
for (int i = 0; i < messages.Length; i++)
{
Console.WriteLine("I'm eating a " + messages[i]); // reading the value
messages[i] = "blabla" + i.ToString(); // writing a value to the array
}
Вы не можете этого сделать (ну, не здраво). Вы считали, что вместо этого используете массив строк?
можете использовать массив? или тип списка?
string[] messages = new string[3];
for (int i = 1; i <=3; i++)
{
messages[i] = "blabla" + i.ToString();
}
Я думаю, вы должны использовать массив для таких переменных.
string[] message = new string[3];
for (int i = 1; i <=3; i++)
{
message[i] = "blabla" + i.ToString();
}
Я бы пошла об этом немного по-другому, может быть, использовать словарь и хранить ваши сообщения. Что-то вроде этого:
Dictionary<string, string> messages = new Dictionary<string, string>();
for(int i = 1; i <= 3; i++)
{
messages.Add("message" + i.ToString(), i.ToString());
}
Вы сказали, что не хотите иметь оператор switch. Я понимаю, что у этого есть переключатель, но если у вас должно быть три разные переменные, вы можете инкапсулировать свой коммутатор внутри вызова функции:
string message1 = null;
string message2 = null;
string message3 = null;
void SetMessage(int i, string value)
{
if(i == 1)
message1 = value;
etc
}
for (int i = 1; i <=3; i++)
{
SetMessage(i, "blabla" + i.ToString());
}
Не оптимальное решение, но если вы ДОЛЖНЫ иметь отдельные переменные, это будет скрыть беспорядок.
Вы также можете сделать это без индекса:
string[] Messages = { "Tom", "Dick", "Harry" };
foreach (String Message in Messages)
{
Response.Write("Hello " + Message + "<br />");
}
Обычно вместо того, чтобы иметь N разных переменных с именами 1, 2, ..., N, следует хранить их в массиве:
string message[3];
message[0] = null;
message[1] = null;
message[2] = null;
, а затем цикл:
for (int i = 0; i <=2; i++)
{
message[i] = "blabla" + i.ToString();
}
Заметим, что обычно снова набор индексированных переменных начинается со значения 0;)